ppb_image_data_proxy.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppb_image_data_proxy.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>  // For memcpy
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_completion_callback.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_resource.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/enter_proxy.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/host_dispatcher.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_dispatcher.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_globals.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_resource_tracker.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/host_resource.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/enter.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/surface/transport_dib.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_ImageData_API;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How ImageData re-use works
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// --------------------------
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When a plugin does ReplaceContents, it transfers the ImageData to the system
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for use as the backing store for the instance. When animating plugins (like
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// video) re-creating image datas for each frame and mapping the memory has a
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// high overhead. So we try to re-use these when possible.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1. Plugin does ReplaceContents and Flush and the proxy queues up an
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    asynchronous request to the renderer.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. Plugin frees its ImageData reference. If it doesn't do this we can't
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    re-use it.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3. When the last plugin ref of an ImageData is released, we don't actually
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    delete it. Instead we put it on a queue where we hold onto it in the
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    plugin process for a short period of time.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4. When the Flush for the Graphics2D.ReplaceContents is executed, the proxy
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    will request the old ImageData. This is the one that's being replaced by
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    the new contents so is being abandoned, and without our caching system it
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    would get deleted at this point.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5. The proxy in the renderer will send NotifyUnusedImageData back to the
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    plugin process. We check if the given resource is in the queue and mark
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    it as usable.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 6. When the plugin requests a new image data, we check our queue and if there
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    is a usable ImageData of the right size and format, we'll return it
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    instead of making a new one. Since when you're doing full frame
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    animations, generally the size doesn't change so cache hits should be
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    high.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some notes:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - We only re-use image datas when the plugin does ReplaceContents on them.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    Theoretically we could re-use them in other cases but the lifetime
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    becomes more difficult to manage. The plugin could have used an ImageData
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    in an arbitrary number of queued up PaintImageData calls which we would
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    have to check. By doing ReplaceContents, the plugin is promising that it's
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    done with the image, so this is a good signal.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - If a flush takes a long time or there are many released image datas
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    accumulating in our queue such that some are deleted, we will have
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    released our reference by the time the renderer notifies us of an unused
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    image data. In this case we just give up.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - We maintain a per-instance cache. Some pages have many instances of
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    Flash, for example, each of a different size. If they're all animating we
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    want each to get its own image data re-use.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - We generate new resource IDs when re-use happens to try to avoid weird
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    problems if the plugin messes up its refcounting.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keep a cache entry for this many seconds before expiring it. We get an entry
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back from the renderer after an ImageData is swapped out, so it means the
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// plugin has to be painting at least two frames for this time interval to
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// get caching.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMaxAgeSeconds = 2;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageDataCacheEntry ---------------------------------------------------------
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ImageDataCacheEntry {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageDataCacheEntry() : added_time(), usable(false), image() {}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageDataCacheEntry(ImageData* i)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : added_time(base::TimeTicks::Now()),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        usable(false),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        image(i) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks added_time;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set to true when the renderer tells us that it's OK to re-use this iamge.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool usable;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ImageData> image;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageDataInstanceCache ------------------------------------------------------
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Per-instance cache of image datas.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageDataInstanceCache {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageDataInstanceCache() : next_insertion_point_(0) {}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These functions have the same spec as the ones in ImageDataCache.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ImageData> Get(int width, int height,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PP_ImageDataFormat format);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Add(ImageData* image_data);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ImageDataUsable(ImageData* image_data);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expires old entries. Returns true if there are still entries in the list,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // false if this instance cache is now empty.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ExpireEntries();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void IncrementInsertionPoint();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We'll store this many ImageDatas per instance.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const static int kCacheSize = 2;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageDataCacheEntry images_[kCacheSize];
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Index into cache where the next item will go.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int next_insertion_point_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<ImageData> ImageDataInstanceCache::Get(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int width, int height,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_ImageDataFormat format) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just do a brute-force search since the cache is so small.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCacheSize; i++) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!images_[i].usable)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_ImageDataDesc& desc = images_[i].image->desc();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (desc.format == format &&
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        desc.size.width == width && desc.size.height == height) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<ImageData> ret(images_[i].image);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      images_[i] = ImageDataCacheEntry();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Since we just removed an item, this entry is the best place to insert
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // a subsequent one.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_insertion_point_ = i;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ret;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_refptr<ImageData>();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataInstanceCache::Add(ImageData* image_data) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  images_[next_insertion_point_] = ImageDataCacheEntry(image_data);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IncrementInsertionPoint();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataInstanceCache::ImageDataUsable(ImageData* image_data) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCacheSize; i++) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (images_[i].image.get() == image_data) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      images_[i].usable = true;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This test is important. The renderer doesn't guarantee how many image
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // datas it has or when it notifies us when one is usable. Its possible
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to get into situations where it's always telling us the old one is
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // usable, and then the older one immediately gets expired. Therefore,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // if the next insertion would overwrite this now-usable entry, make the
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // next insertion overwrite some other entry to avoid the replacement.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (next_insertion_point_ == i)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IncrementInsertionPoint();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageDataInstanceCache::ExpireEntries() {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks threshold_time =
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeTicks::Now() - base::TimeDelta::FromSeconds(kMaxAgeSeconds);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_entry = false;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCacheSize; i++) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (images_[i].image.get()) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Entry present.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (images_[i].added_time <= threshold_time) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Found an entry to expire.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        images_[i] = ImageDataCacheEntry();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        next_insertion_point_ = i;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Found an entry that we're keeping.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        has_entry = true;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return has_entry;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataInstanceCache::IncrementInsertionPoint() {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go to the next location, wrapping around to get LRU.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_insertion_point_++;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (next_insertion_point_ >= kCacheSize)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_insertion_point_ = 0;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageDataCache --------------------------------------------------------------
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageDataCache {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageDataCache() : weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ImageDataCache() {}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ImageDataCache* GetInstance();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves an image data from the cache of the specified size and format if
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one exists. If one doesn't exist, this will return a null refptr.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ImageData> Get(PP_Instance instance,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               int width, int height,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PP_ImageDataFormat format);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds the given image data to the cache. There should be no plugin
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // references to it. This may delete an older item from the cache.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Add(ImageData* image_data);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notification from the renderer that the given image data is usable.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ImageDataUsable(ImageData* image_data);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DidDeleteInstance(PP_Instance instance);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct LeakySingletonTraits<ImageDataCache>;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timer callback to expire entries for the given instance.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnTimer(PP_Instance instance);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This class does timer calls and we don't want to run these outside of the
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scope of the object. Technically, since this class is a leaked static,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this will never happen and this factory is unnecessary. However, it's
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // probably better not to make assumptions about the lifetime of this class.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<ImageDataCache> weak_factory_;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<PP_Instance, ImageDataInstanceCache> CacheMap;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CacheMap cache_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageDataCache);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageDataCache* ImageDataCache::GetInstance() {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Singleton<ImageDataCache,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   LeakySingletonTraits<ImageDataCache> >::get();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<ImageData> ImageDataCache::Get(PP_Instance instance,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int width, int height,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             PP_ImageDataFormat format) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CacheMap::iterator found = cache_.find(instance);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == cache_.end())
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return scoped_refptr<ImageData>();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return found->second.Get(width, height, format);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataCache::Add(ImageData* image_data) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_[image_data->pp_instance()].Add(image_data);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedule a timer to invalidate this entry.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageLoop::current()->PostDelayedTask(
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RunWhileLocked(base::Bind(&ImageDataCache::OnTimer,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     weak_factory_.GetWeakPtr(),
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     image_data->pp_instance())),
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromSeconds(kMaxAgeSeconds));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataCache::ImageDataUsable(ImageData* image_data) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CacheMap::iterator found = cache_.find(image_data->pp_instance());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found != cache_.end())
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    found->second.ImageDataUsable(image_data);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ImageDataCache::DidDeleteInstance(PP_Instance instance) {
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache_.erase(instance);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataCache::OnTimer(PP_Instance instance) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CacheMap::iterator found = cache_.find(instance);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == cache_.end())
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!found->second.ExpireEntries()) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There are no more entries for this instance, remove it from the cache.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache_.erase(found);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageData -------------------------------------------------------------------
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::ImageData(const HostResource& resource,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const PP_ImageDataDesc& desc,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ImageHandle handle)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(OBJECT_IS_PROXY, resource),
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      desc_(desc),
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      used_in_replace_contents_(false) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_dib_.reset(TransportDIB::CreateWithHandle(handle));
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_dib_.reset(TransportDIB::Map(handle));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // !defined(OS_NACL)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::ImageData(const HostResource& resource,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const PP_ImageDataDesc& desc,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const base::SharedMemoryHandle& handle)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(OBJECT_IS_PROXY, resource),
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      desc_(desc),
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shm_(handle, false /* read_only */),
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_(desc.size.width * desc.size.height * 4),
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map_count_(0),
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      used_in_replace_contents_(false) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // else, !defined(OS_NACL)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::~ImageData() {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_API* ImageData::AsPPB_ImageData_API() {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageData::LastPluginRefWasDeleted() {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The plugin no longer needs this ImageData, add it to our cache if it's
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been used in a ReplaceContents. These are the ImageDatas that the renderer
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will send back ImageDataUsable messages for.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (used_in_replace_contents_)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ImageDataCache::GetInstance()->Add(this);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ImageData::InstanceWasDeleted() {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ImageDataCache::GetInstance()->DidDeleteInstance(pp_instance());
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(desc, &desc_, sizeof(PP_ImageDataDesc));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ImageData::Map() {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (map_count_++ == 0)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shm_.Map(size_);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shm_.memory();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mapped_canvas_.get()) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width,
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           desc_.size.height));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!mapped_canvas_.get())
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkBitmap& bitmap =
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.lockPixels();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bitmap.getAddr(0, 0);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageData::Unmap() {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (--map_count_ == 0)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shm_.Unmap();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) have a way to unmap a TransportDIB. Currently this isn't
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // possible since deleting the TransportDIB also frees all the handles.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to add a method to TransportDIB to release the handles.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t ImageData::GetSharedMemory(int* /* handle */,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   uint32_t* /* byte_count */) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not supported in the proxy (this method is for actually implementing the
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy in the host).
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_ERROR_NOACCESS;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkCanvas* ImageData::GetPlatformCanvas() {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;  // No canvas in NaCl.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mapped_canvas_.get();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkCanvas* ImageData::GetCanvas() {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;  // No canvas in NaCl.
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mapped_canvas_.get();
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ImageData::SetUsedInReplaceContents() {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  used_in_replace_contents_ = true;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageData::RecycleToPlugin(bool zero_contents) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  used_in_replace_contents_ = false;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (zero_contents) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* data = Map();
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(data, 0, desc_.stride * desc_.size.height);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Unmap();
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageHandle ImageData::NullHandle() {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) || defined(OS_ANDROID)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ImageHandle();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageHandle ImageData::HandleFromInt(int32_t i) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<ImageHandle>(i);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) || defined(OS_ANDROID)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ImageHandle(i, false);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<ImageHandle>(i);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(OS_NACL)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPB_ImageData_Proxy ---------------------------------------------------------
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : InterfaceProxy(dispatcher) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_Proxy::~PPB_ImageData_Proxy() {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource PPB_ImageData_Proxy::CreateProxyResource(PP_Instance instance,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     PP_ImageDataFormat format,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     const PP_Size& size,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     PP_Bool init_to_zero) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dispatcher)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the cache.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ImageData> cached_image_data =
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImageDataCache::GetInstance()->Get(instance, size.width, size.height,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         format);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cached_image_data.get()) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have one we can re-use rather than allocating a new one.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cached_image_data->RecycleToPlugin(PP_ToBool(init_to_zero));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cached_image_data->GetReference();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResource result;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string image_data_desc;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppapi::proxy::SerializedHandle image_handle_wrapper;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher->Send(new PpapiHostMsg_PPBImageData_CreateNaCl(
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kApiID, instance, format, size, init_to_zero,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &result, &image_data_desc, &image_handle_wrapper));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!image_handle_wrapper.is_shmem())
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SharedMemoryHandle image_handle = image_handle_wrapper.shmem();
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageHandle image_handle = ImageData::NullHandle();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher->Send(new PpapiHostMsg_PPBImageData_Create(
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kApiID, instance, format, size, init_to_zero,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &result, &image_data_desc, &image_handle));
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc))
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We serialize the PP_ImageDataDesc just by copying to a string.
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_ImageDataDesc desc;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (new ImageData(result, desc, image_handle))->GetReference();
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_NACL)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnHostMsgCreate)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreateNaCl,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnHostMsgCreateNaCl)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData,
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnPluginMsgNotifyUnusedImageData)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_NACL)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance,
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          int32_t format,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const PP_Size& size,
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          PP_Bool init_to_zero,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          HostResource* result,
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          std::string* image_data_desc,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          ImageHandle* result_image_handle) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result_image_handle = ImageData::NullHandle();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thunk::EnterResourceCreation enter(instance);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter.failed())
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource resource = enter.functions()->CreateImageData(
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resource)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->SetHostResource(instance, resource);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the description, it's just serialized as a string.
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource, false);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_ImageDataDesc desc;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter_resource.object()->Describe(&desc) == PP_TRUE) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_data_desc->resize(sizeof(PP_ImageDataDesc));
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the shared memory handle.
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t byte_count = 0;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t handle = 0;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter_resource.object()->GetSharedMemory(&handle, &byte_count) == PP_OK) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ImageHandle ih = ImageData::HandleFromInt(handle);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result_image_handle = ImageData::HandleFromInt(handle);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_ImageData_Proxy::OnHostMsgCreateNaCl(
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t format,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Size& size,
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Bool init_to_zero,
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResource* result,
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* image_data_desc,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ppapi::proxy::SerializedHandle* result_image_handle) {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_image_handle->set_null_shmem();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dispatcher)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thunk::EnterResourceCreation enter(instance);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter.failed())
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource resource = enter.functions()->CreateImageDataNaCl(
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resource)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->SetHostResource(instance, resource);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the description, it's just serialized as a string.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource, false);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter_resource.failed())
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_ImageDataDesc desc;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter_resource.object()->Describe(&desc) == PP_TRUE) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_data_desc->resize(sizeof(PP_ImageDataDesc));
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int local_fd;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t byte_count;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter_resource.object()->GetSharedMemory(&local_fd, &byte_count) != PP_OK)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(dmichael): Change trusted interface to return a PP_FileHandle, those
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // casts are ugly.
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFile platform_file =
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd));
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      local_fd;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #error Not implemented.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_image_handle->set_shmem(
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->ShareHandleWithRemote(platform_file, false),
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      byte_count);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(OS_NACL)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData(
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HostResource& old_image_data) {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginGlobals* plugin_globals = PluginGlobals::Get();
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!plugin_globals)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // This may happen if the plugin is maliciously sending this
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             // message to the renderer.
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter.succeeded()) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ImageData* image_data = static_cast<ImageData*>(enter.object());
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ImageDataCache::GetInstance()->ImageDataUsable(image_data);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The renderer sent us a reference with the message. If the image data was
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // still cached in our process, the proxy still holds a reference so we can
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // remove the one the renderer just sent is. If the proxy no longer holds a
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reference, we released everything and we should also release the one the
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // renderer just sent us.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPB_CORE, old_image_data));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
640