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" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/shared_impl/scoped_pp_resource.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/enter.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/surface/transport_dib.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_ImageData_API; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How ImageData re-use works 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------- 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// When animating plugins (like video), re-creating image datas for each frame 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// and mapping the memory has a high overhead. So we try to re-use these when 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// possible. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 1. Plugin makes an asynchronous call that transfers an ImageData to the 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// implementation of some API. 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. 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 4. The API implementation that received the ImageData finishes using it. 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Without our caching system it would get deleted at this point. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5. The proxy in the renderer will send NotifyUnusedImageData back to the 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// plugin process. We check if the given resource is in the queue and mark 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it as usable. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 6. When the plugin requests a new image data, we check our queue and if there 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is a usable ImageData of the right size and format, we'll return it 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// instead of making a new one. It's important that caching is only requested 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// when the size is unlikely to change, so cache hits are high. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some notes: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - We only re-use image data when the plugin and host are rapidly exchanging 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// them and the size is likely to remain constant. It should be clear that 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the plugin is promising that it's done with the image. 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (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 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// have to check. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If a flush takes a long time or there are many released image datas 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// accumulating in our queue such that some are deleted, we will have 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// released our reference by the time the renderer notifies us of an unused 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// image data. In this case we just give up. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - We maintain a per-instance cache. Some pages have many instances of 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flash, for example, each of a different size. If they're all animating we 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// want each to get its own image data re-use. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - We generate new resource IDs when re-use happens to try to avoid weird 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// problems if the plugin messes up its refcounting. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keep a cache entry for this many seconds before expiring it. We get an entry 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back from the renderer after an ImageData is swapped out, so it means the 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// plugin has to be painting at least two frames for this time interval to 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// get caching. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMaxAgeSeconds = 2; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageDataCacheEntry --------------------------------------------------------- 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ImageDataCacheEntry { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageDataCacheEntry() : added_time(), usable(false), image() {} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageDataCacheEntry(ImageData* i) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : added_time(base::TimeTicks::Now()), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usable(false), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image(i) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks added_time; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to true when the renderer tells us that it's OK to re-use this iamge. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool usable; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ImageData> image; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageDataInstanceCache ------------------------------------------------------ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Per-instance cache of image datas. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageDataInstanceCache { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageDataInstanceCache() : next_insertion_point_(0) {} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These functions have the same spec as the ones in ImageDataCache. 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<ImageData> Get(PPB_ImageData_Shared::ImageDataType type, 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 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( 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::ImageDataType type, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width, int height, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_ImageDataFormat format) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just do a brute-force search since the cache is so small. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kCacheSize; i++) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!images_[i].usable) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (images_[i].image->type() != type) 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) continue; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_ImageDataDesc& desc = images_[i].image->desc(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (desc.format == format && 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc.size.width == width && desc.size.height == height) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ImageData> ret(images_[i].image); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_[i] = ImageDataCacheEntry(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we just removed an item, this entry is the best place to insert 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a subsequent one. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_insertion_point_ = i; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_refptr<ImageData>(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataInstanceCache::Add(ImageData* image_data) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_[next_insertion_point_] = ImageDataCacheEntry(image_data); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementInsertionPoint(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataInstanceCache::ImageDataUsable(ImageData* image_data) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kCacheSize; i++) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (images_[i].image.get() == image_data) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_[i].usable = true; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This test is important. The renderer doesn't guarantee how many image 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // datas it has or when it notifies us when one is usable. Its possible 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to get into situations where it's always telling us the old one is 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // usable, and then the older one immediately gets expired. Therefore, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the next insertion would overwrite this now-usable entry, make the 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // next insertion overwrite some other entry to avoid the replacement. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_insertion_point_ == i) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementInsertionPoint(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageDataInstanceCache::ExpireEntries() { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks threshold_time = 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - base::TimeDelta::FromSeconds(kMaxAgeSeconds); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_entry = false; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kCacheSize; i++) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (images_[i].image.get()) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Entry present. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (images_[i].added_time <= threshold_time) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Found an entry to expire. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_[i] = ImageDataCacheEntry(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_insertion_point_ = i; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Found an entry that we're keeping. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_entry = true; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return has_entry; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataInstanceCache::IncrementInsertionPoint() { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Go to the next location, wrapping around to get LRU. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_insertion_point_++; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_insertion_point_ >= kCacheSize) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_insertion_point_ = 0; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageDataCache -------------------------------------------------------------- 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageDataCache { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ImageDataCache() : weak_factory_(this) {} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ImageDataCache() {} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ImageDataCache* GetInstance(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Retrieves an image data from the cache of the specified type, size and 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // format if one exists. If one doesn't exist, this will return a null refptr. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ImageData> Get(PP_Instance instance, 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::ImageDataType type, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width, int height, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_ImageDataFormat format); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the given image data to the cache. There should be no plugin 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // references to it. This may delete an older item from the cache. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Add(ImageData* image_data); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notification from the renderer that the given image data is usable. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ImageDataUsable(ImageData* image_data); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DidDeleteInstance(PP_Instance instance); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct LeakySingletonTraits<ImageDataCache>; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Timer callback to expire entries for the given instance. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnTimer(PP_Instance instance); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) typedef std::map<PP_Instance, ImageDataInstanceCache> CacheMap; 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CacheMap cache_; 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This class does timer calls and we don't want to run these outside of the 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scope of the object. Technically, since this class is a leaked static, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this will never happen and this factory is unnecessary. However, it's 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // probably better not to make assumptions about the lifetime of this class. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ImageDataCache> weak_factory_; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageDataCache); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageDataCache* ImageDataCache::GetInstance() { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<ImageDataCache, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LeakySingletonTraits<ImageDataCache> >::get(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_refptr<ImageData> ImageDataCache::Get( 2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Instance instance, 2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::ImageDataType type, 2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int width, int height, 2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_ImageDataFormat format) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheMap::iterator found = cache_.find(instance); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == cache_.end()) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_refptr<ImageData>(); 2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return found->second.Get(type, width, height, format); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataCache::Add(ImageData* image_data) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_[image_data->pp_instance()].Add(image_data); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule a timer to invalidate this entry. 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunWhileLocked(base::Bind(&ImageDataCache::OnTimer, 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_.GetWeakPtr(), 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) image_data->pp_instance())), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(kMaxAgeSeconds)); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataCache::ImageDataUsable(ImageData* image_data) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheMap::iterator found = cache_.find(image_data->pp_instance()); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found != cache_.end()) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found->second.ImageDataUsable(image_data); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ImageDataCache::DidDeleteInstance(PP_Instance instance) { 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cache_.erase(instance); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataCache::OnTimer(PP_Instance instance) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheMap::iterator found = cache_.find(instance); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == cache_.end()) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found->second.ExpireEntries()) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There are no more entries for this instance, remove it from the cache. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_.erase(found); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageData ------------------------------------------------------------------- 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::ImageData(const HostResource& resource, 3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::ImageDataType type, 3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_ImageDataDesc& desc) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Resource(OBJECT_IS_PROXY, resource), 3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) type_(type), 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_(desc), 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) is_candidate_for_reuse_(false) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::~ImageData() { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_API* ImageData::AsPPB_ImageData_API() { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageData::LastPluginRefWasDeleted() { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The plugin no longer needs this ImageData, add it to our cache if it's 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // been used in a ReplaceContents. These are the ImageDatas that the renderer 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will send back ImageDataUsable messages for. 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (is_candidate_for_reuse_) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageDataCache::GetInstance()->Add(this); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ImageData::InstanceWasDeleted() { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ImageDataCache::GetInstance()->DidDeleteInstance(pp_instance()); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t ImageData::GetSharedMemory(int* /* handle */, 3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uint32_t* /* byte_count */) { 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Not supported in the proxy (this method is for actually implementing the 3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // proxy in the host). 3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_NOACCESS; 3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ImageData::SetIsCandidateForReuse() { 3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) is_candidate_for_reuse_ = true; 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ImageData::RecycleToPlugin(bool zero_contents) { 3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) is_candidate_for_reuse_ = false; 3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (zero_contents) { 3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void* data = Map(); 3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) memset(data, 0, desc_.stride * desc_.size.height); 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Unmap(); 3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// PlatformImageData ----------------------------------------------------------- 3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if !defined(OS_NACL) 3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PlatformImageData::PlatformImageData(const HostResource& resource, 3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_ImageDataDesc& desc, 3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ImageHandle handle) 3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : ImageData(resource, PPB_ImageData_Shared::PLATFORM, desc) { 3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN) 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) transport_dib_.reset(TransportDIB::Map(handle)); 3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif // defined(OS_WIN) 3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PlatformImageData::~PlatformImageData() { 3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void* PlatformImageData::Map() { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!mapped_canvas_.get()) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_.size.height)); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!mapped_canvas_.get()) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& bitmap = 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.lockPixels(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bitmap.getAddr(0, 0); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PlatformImageData::Unmap() { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(brettw) have a way to unmap a TransportDIB. Currently this isn't 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible since deleting the TransportDIB also frees all the handles. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to add a method to TransportDIB to release the handles. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SkCanvas* PlatformImageData::GetPlatformCanvas() { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mapped_canvas_.get(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SkCanvas* PlatformImageData::GetCanvas() { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mapped_canvas_.get(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ImageHandle PlatformImageData::NullHandle() { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ImageHandle(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ImageHandle PlatformImageData::HandleFromInt(int32_t i) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<ImageHandle>(i); 42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ImageHandle(i, false); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_NACL) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// SimpleImageData ------------------------------------------------------------- 4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SimpleImageData::SimpleImageData(const HostResource& resource, 4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_ImageDataDesc& desc, 4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::SharedMemoryHandle& handle) 4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : ImageData(resource, PPB_ImageData_Shared::SIMPLE, desc), 4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shm_(handle, false /* read_only */), 4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_(desc.size.width * desc.size.height * 4), 4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) map_count_(0) { 4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SimpleImageData::~SimpleImageData() { 4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void* SimpleImageData::Map() { 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (map_count_++ == 0) 4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shm_.Map(size_); 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return shm_.memory(); 4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SimpleImageData::Unmap() { 4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (--map_count_ == 0) 4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shm_.Unmap(); 4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SkCanvas* SimpleImageData::GetPlatformCanvas() { 4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return NULL; // No canvas available. 4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SkCanvas* SimpleImageData::GetCanvas() { 4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return NULL; // No canvas available. 4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPB_ImageData_Proxy --------------------------------------------------------- 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : InterfaceProxy(dispatcher) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PP_Resource PPB_ImageData_Proxy::CreateProxyResource( 4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Instance instance, 4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::ImageDataType type, 4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_ImageDataFormat format, 4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_Size& size, 4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Bool init_to_zero) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dispatcher) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the cache. 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ImageData> cached_image_data = 4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ImageDataCache::GetInstance()->Get(instance, type, 4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size.width, size.height, format); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cached_image_data.get()) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have one we can re-use rather than allocating a new one. 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cached_image_data->RecycleToPlugin(PP_ToBool(init_to_zero)); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cached_image_data->GetReference(); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResource result; 4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_ImageDataDesc desc; 4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch (type) { 4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case PPB_ImageData_Shared::SIMPLE: { 5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ppapi::proxy::SerializedHandle image_handle_wrapper; 5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dispatcher->Send(new PpapiHostMsg_PPBImageData_CreateSimple( 5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kApiID, instance, format, size, init_to_zero, 5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &result, &desc, &image_handle_wrapper)); 5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (image_handle_wrapper.is_shmem()) { 5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::SharedMemoryHandle image_handle = image_handle_wrapper.shmem(); 5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!result.is_null()) 5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return 5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (new SimpleImageData(result, desc, image_handle))->GetReference(); 5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case PPB_ImageData_Shared::PLATFORM: { 5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if !defined(OS_NACL) 5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ImageHandle image_handle = PlatformImageData::NullHandle(); 5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dispatcher->Send(new PpapiHostMsg_PPBImageData_CreatePlatform( 5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kApiID, instance, format, size, init_to_zero, 5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &result, &desc, &image_handle)); 5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!result.is_null()) 5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return 5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (new PlatformImageData(result, desc, image_handle))->GetReference(); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // PlatformImageData shouldn't be created in untrusted code. 5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NOTREACHED(); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return 0; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_NACL) 5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreatePlatform, 5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) OnHostMsgCreatePlatform) 5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreateSimple, 5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) OnHostMsgCreateSimple) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPluginMsgNotifyUnusedImageData) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_NACL) 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PP_Resource PPB_ImageData_Proxy::CreateImageData( 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Instance instance, 5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::ImageDataType type, 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_ImageDataFormat format, 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const PP_Size& size, 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool init_to_zero, 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_ImageDataDesc* desc, 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC::PlatformFileForTransit* image_handle, 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32_t* byte_count) { 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!dispatcher) 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thunk::EnterResourceCreation enter(instance); 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (enter.failed()) 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Bool pp_init_to_zero = init_to_zero ? PP_TRUE : PP_FALSE; 569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_Resource pp_resource = 0; 570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch switch (type) { 571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PPB_ImageData_Shared::SIMPLE: { 572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp_resource = enter.functions()->CreateImageDataSimple( 573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch instance, format, &size, pp_init_to_zero); 574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PPB_ImageData_Shared::PLATFORM: { 577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp_resource = enter.functions()->CreateImageData( 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch instance, format, &size, pp_init_to_zero); 579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!pp_resource) 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ppapi::ScopedPPResource resource(ppapi::ScopedPPResource::PassRef(), 587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp_resource); 588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource.get(), 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false); 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (enter_resource.object()->Describe(desc) != PP_TRUE) { 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "CreateImageData failed: could not Describe"; 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int local_fd = 0; 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (enter_resource.object()->GetSharedMemory(&local_fd, 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) byte_count) != PP_OK) { 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "CreateImageData failed: could not GetSharedMemory"; 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN) 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *image_handle = dispatcher->ShareHandleWithRemote( 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)), false); 60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#elif defined(OS_POSIX) 60790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #error Not implemented. 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return resource.Release(); 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PPB_ImageData_Proxy::OnHostMsgCreatePlatform( 6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Instance instance, 6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int32_t format, 6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_Size& size, 6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Bool init_to_zero, 6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) HostResource* result, 6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_ImageDataDesc* desc, 6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ImageHandle* result_image_handle) { 623116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Clear |desc| so we don't send unitialized memory to the plugin. 624116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // https://crbug.com/391023. 625116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *desc = PP_ImageDataDesc(); 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC::PlatformFileForTransit image_handle; 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32_t byte_count; 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource resource = 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateImageData(instance, 6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::PLATFORM, 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<PP_ImageDataFormat>(format), 632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size, 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true /* init_to_zero */, 6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) desc, &image_handle, &byte_count); 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->SetHostResource(instance, resource); 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (resource) { 63790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *result_image_handle = image_handle; 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *result_image_handle = PlatformImageData::NullHandle(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PPB_ImageData_Proxy::OnHostMsgCreateSimple( 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Instance instance, 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t format, 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_Size& size, 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool init_to_zero, 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResource* result, 6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_ImageDataDesc* desc, 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ppapi::proxy::SerializedHandle* result_image_handle) { 651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Clear |desc| so we don't send unitialized memory to the plugin. 652116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // https://crbug.com/391023. 653116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *desc = PP_ImageDataDesc(); 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC::PlatformFileForTransit image_handle; 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32_t byte_count; 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource resource = 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateImageData(instance, 6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PPB_ImageData_Shared::SIMPLE, 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<PP_ImageDataFormat>(format), 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size, 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true /* init_to_zero */, 6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) desc, &image_handle, &byte_count); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetHostResource(instance, resource); 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (resource) { 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result_image_handle->set_shmem(image_handle, byte_count); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result_image_handle->set_null_shmem(); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // !defined(OS_NACL) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData( 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HostResource& old_image_data) { 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginGlobals* plugin_globals = PluginGlobals::Get(); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!plugin_globals) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // This may happen if the plugin is maliciously sending this 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message to the renderer. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enter.succeeded()) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageData* image_data = static_cast<ImageData*>(enter.object()); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageDataCache::GetInstance()->ImageDataUsable(image_data); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The renderer sent us a reference with the message. If the image data was 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // still cached in our process, the proxy still holds a reference so we can 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remove the one the renderer just sent is. If the proxy no longer holds a 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference, we released everything and we should also release the one the 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // renderer just sent us. 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource( 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) API_ID_PPB_CORE, old_image_data)); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 697