Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/pepper/ppb_image_data_impl.h" | 5 #include "content/renderer/pepper/ppb_image_data_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "content/common/view_messages.h" | 12 #include "content/common/view_messages.h" |
| 13 #include "content/renderer/pepper/common.h" | 13 #include "content/renderer/pepper/common.h" |
| 14 #include "content/renderer/render_thread_impl.h" | 14 #include "content/renderer/render_thread_impl.h" |
| 15 #include "ppapi/c/pp_errors.h" | 15 #include "ppapi/c/pp_errors.h" |
| 16 #include "ppapi/c/pp_instance.h" | 16 #include "ppapi/c/pp_instance.h" |
| 17 #include "ppapi/c/pp_resource.h" | 17 #include "ppapi/c/pp_resource.h" |
| 18 #include "ppapi/c/ppb_image_data.h" | 18 #include "ppapi/c/ppb_image_data.h" |
| 19 #include "ppapi/thunk/thunk.h" | 19 #include "ppapi/thunk/thunk.h" |
| 20 #include "skia/ext/platform_canvas.h" | 20 #include "skia/ext/platform_canvas.h" |
| 21 #include "third_party/skia/include/core/SkColorPriv.h" | 21 #include "third_party/skia/include/core/SkColorPriv.h" |
| 22 #include "ui/surface/transport_dib.h" | 22 #include "ui/surface/transport_dib.h" |
| 23 | 23 |
| 24 using ppapi::thunk::PPB_ImageData_API; | 24 using ppapi::thunk::PPB_ImageData_API; |
| 25 | 25 |
| 26 namespace content { | 26 namespace content { |
| 27 | 27 |
| 28 PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, | 28 PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, |
| 29 PPB_ImageData_Shared::ImageDataType type) | 29 PPB_ImageData_Shared::ImageDataType type, |
| 30 bool is_browser_allocated) | |
|
bbudge
2013/11/11 12:24:06
Couldn't we just call IsBrowserAllocated on the ty
bbudge
2013/11/11 19:09:15
Never mind, I realized this is the whole point of
| |
| 30 : Resource(ppapi::OBJECT_IS_IMPL, instance), | 31 : Resource(ppapi::OBJECT_IS_IMPL, instance), |
| 31 format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL), | 32 format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL), |
| 32 width_(0), | 33 width_(0), |
| 33 height_(0) { | 34 height_(0) { |
| 34 switch (type) { | 35 switch (type) { |
| 35 case PPB_ImageData_Shared::PLATFORM: | 36 case PPB_ImageData_Shared::PLATFORM: |
| 36 backend_.reset(new ImageDataPlatformBackend); | 37 backend_.reset(new ImageDataPlatformBackend(is_browser_allocated)); |
| 37 return; | 38 return; |
| 38 case PPB_ImageData_Shared::SIMPLE: | 39 case PPB_ImageData_Shared::SIMPLE: |
| 40 DCHECK(!is_browser_allocated) << | |
| 41 "PPB_ImageData_Shared::SIMPLE is always allocated in the renderer."; | |
| 39 backend_.reset(new ImageDataSimpleBackend); | 42 backend_.reset(new ImageDataSimpleBackend); |
| 40 return; | 43 return; |
| 41 // No default: so that we get a compiler warning if any types are added. | 44 // No default: so that we get a compiler warning if any types are added. |
| 42 } | 45 } |
| 43 NOTREACHED(); | 46 NOTREACHED(); |
| 44 } | 47 } |
| 45 | 48 |
| 46 PPB_ImageData_Impl::~PPB_ImageData_Impl() { | 49 PPB_ImageData_Impl::~PPB_ImageData_Impl() { |
| 47 } | 50 } |
| 48 | 51 |
| 52 // static | |
| 53 bool PPB_ImageData_Impl::IsBrowserAllocated(ImageDataType format) { | |
| 54 if (format == PPB_ImageData_Shared::SIMPLE) | |
| 55 return false; | |
| 56 #if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) | |
| 57 // On the Mac, shared memory has to be created in the browser in order to | |
| 58 // work in the sandbox. | |
| 59 return true; | |
| 60 #endif | |
| 61 return false; | |
| 62 } | |
| 63 | |
| 49 bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format, | 64 bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format, |
| 50 int width, int height, | 65 int width, int height, |
| 51 bool init_to_zero) { | 66 bool init_to_zero) { |
| 52 // TODO(brettw) this should be called only on the main thread! | 67 // TODO(brettw) this should be called only on the main thread! |
| 53 if (!IsImageDataFormatSupported(format)) | 68 if (!IsImageDataFormatSupported(format)) |
| 54 return false; // Only support this one format for now. | 69 return false; // Only support this one format for now. |
| 55 if (width <= 0 || height <= 0) | 70 if (width <= 0 || height <= 0) |
| 56 return false; | 71 return false; |
| 57 if (static_cast<int64>(width) * static_cast<int64>(height) >= | 72 if (static_cast<int64>(width) * static_cast<int64>(height) >= |
| 58 std::numeric_limits<int32>::max() / 4) | 73 std::numeric_limits<int32>::max() / 4) |
| 59 return false; // Prevent overflow of signed 32-bit ints. | 74 return false; // Prevent overflow of signed 32-bit ints. |
| 60 | 75 |
| 61 format_ = format; | 76 format_ = format; |
| 62 width_ = width; | 77 width_ = width; |
| 63 height_ = height; | 78 height_ = height; |
| 64 return backend_->Init(this, format, width, height, init_to_zero); | 79 return backend_->Init(this, format, width, height, init_to_zero); |
| 65 } | 80 } |
| 66 | 81 |
| 67 // static | 82 // static |
| 68 PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance, | 83 PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance, |
| 69 PPB_ImageData_Shared::ImageDataType type, | 84 PPB_ImageData_Shared::ImageDataType type, |
| 70 PP_ImageDataFormat format, | 85 PP_ImageDataFormat format, |
| 71 const PP_Size& size, | 86 const PP_Size& size, |
| 72 PP_Bool init_to_zero) { | 87 PP_Bool init_to_zero) { |
| 73 scoped_refptr<PPB_ImageData_Impl> | 88 scoped_refptr<PPB_ImageData_Impl> |
| 74 data(new PPB_ImageData_Impl(instance, type)); | 89 data(new PPB_ImageData_Impl(instance, type, IsBrowserAllocated(type))); |
| 75 if (!data->Init(format, size.width, size.height, !!init_to_zero)) | 90 if (!data->Init(format, size.width, size.height, !!init_to_zero)) |
| 76 return 0; | 91 return 0; |
| 77 return data->GetReference(); | 92 return data->GetReference(); |
| 78 } | 93 } |
| 79 | 94 |
| 80 PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { | 95 PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { |
| 81 return this; | 96 return this; |
| 82 } | 97 } |
| 83 | 98 |
| 84 bool PPB_ImageData_Impl::IsMapped() const { | 99 bool PPB_ImageData_Impl::IsMapped() const { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 void PPB_ImageData_Impl::SetIsCandidateForReuse() { | 135 void PPB_ImageData_Impl::SetIsCandidateForReuse() { |
| 121 // Nothing to do since we don't support image data re-use in-process. | 136 // Nothing to do since we don't support image data re-use in-process. |
| 122 } | 137 } |
| 123 | 138 |
| 124 const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const { | 139 const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const { |
| 125 return backend_->GetMappedBitmap(); | 140 return backend_->GetMappedBitmap(); |
| 126 } | 141 } |
| 127 | 142 |
| 128 // ImageDataPlatformBackend ---------------------------------------------------- | 143 // ImageDataPlatformBackend ---------------------------------------------------- |
| 129 | 144 |
| 130 ImageDataPlatformBackend::ImageDataPlatformBackend() | 145 ImageDataPlatformBackend::ImageDataPlatformBackend(bool is_browser_allocated) |
| 131 : width_(0), | 146 : width_(0), |
| 132 height_(0) { | 147 height_(0), |
| 148 is_browser_allocated_(is_browser_allocated) { | |
| 133 } | 149 } |
| 134 | 150 |
| 135 // On POSIX, we have to tell the browser to free the transport DIB. | 151 // On POSIX, we have to tell the browser to free the transport DIB. |
| 136 ImageDataPlatformBackend::~ImageDataPlatformBackend() { | 152 ImageDataPlatformBackend::~ImageDataPlatformBackend() { |
| 137 #if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) | 153 if (is_browser_allocated_) { |
| 138 if (dib_) { | 154 if (dib_) { |
| 139 RenderThreadImpl::current()->Send( | 155 RenderThreadImpl::current()->Send( |
| 140 new ViewHostMsg_FreeTransportDIB(dib_->id())); | 156 new ViewHostMsg_FreeTransportDIB(dib_->id())); |
| 157 } | |
| 141 } | 158 } |
| 142 #endif | |
| 143 } | 159 } |
| 144 | 160 |
| 145 bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl, | 161 bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl, |
| 146 PP_ImageDataFormat format, | 162 PP_ImageDataFormat format, |
| 147 int width, int height, | 163 int width, int height, |
| 148 bool init_to_zero) { | 164 bool init_to_zero) { |
| 149 // TODO(brettw) use init_to_zero when we implement caching. | 165 // TODO(brettw) use init_to_zero when we implement caching. |
| 150 width_ = width; | 166 width_ = width; |
| 151 height_ = height; | 167 height_ = height; |
| 152 uint32 buffer_size = width_ * height_ * 4; | 168 uint32 buffer_size = width_ * height_ * 4; |
| 153 | 169 |
| 154 // Allocate the transport DIB and the PlatformCanvas pointing to it. | 170 // Allocate the transport DIB and the PlatformCanvas pointing to it. |
| 155 #if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) | 171 TransportDIB* dib = NULL; |
| 156 // On the Mac, shared memory has to be created in the browser in order to | 172 if (is_browser_allocated_) { |
| 157 // work in the sandbox. Do this by sending a message to the browser | 173 // Allocate the image data by sending a message to the browser requesting a |
| 158 // requesting a TransportDIB (see also | 174 // TransportDIB (see also chrome/renderer/webplugin_delegate_proxy.cc, |
| 159 // chrome/renderer/webplugin_delegate_proxy.cc, method | 175 // method WebPluginDelegateProxy::CreateBitmap() for similar code). The |
| 160 // WebPluginDelegateProxy::CreateBitmap() for similar code). The TransportDIB | 176 // TransportDIB is cached in the browser, and is freed (in typical cases) by |
| 161 // is cached in the browser, and is freed (in typical cases) by the | 177 // the TransportDIB's destructor. |
| 162 // TransportDIB's destructor. | 178 TransportDIB::Handle dib_handle; |
| 163 TransportDIB::Handle dib_handle; | 179 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size, |
| 164 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size, | 180 true, |
| 165 true, | 181 &dib_handle); |
| 166 &dib_handle); | 182 if (!RenderThreadImpl::current()->Send(msg)) |
| 167 if (!RenderThreadImpl::current()->Send(msg)) | 183 return false; |
| 168 return false; | 184 if (!TransportDIB::is_valid_handle(dib_handle)) |
| 169 if (!TransportDIB::is_valid_handle(dib_handle)) | 185 return false; |
| 170 return false; | |
| 171 | 186 |
| 172 TransportDIB* dib = TransportDIB::CreateWithHandle(dib_handle); | 187 dib = TransportDIB::CreateWithHandle(dib_handle); |
| 173 #else | 188 } else { |
| 174 static int next_dib_id = 0; | 189 static int next_dib_id = 0; |
| 175 TransportDIB* dib = TransportDIB::Create(buffer_size, next_dib_id++); | 190 dib = TransportDIB::Create(buffer_size, next_dib_id++); |
| 176 if (!dib) | 191 if (!dib) |
| 177 return false; | 192 return false; |
| 178 #endif | 193 } |
| 179 dib_.reset(dib); | 194 dib_.reset(dib); |
| 180 return true; | 195 return true; |
| 181 } | 196 } |
| 182 | 197 |
| 183 bool ImageDataPlatformBackend::IsMapped() const { | 198 bool ImageDataPlatformBackend::IsMapped() const { |
| 184 return !!mapped_canvas_.get(); | 199 return !!mapped_canvas_.get(); |
| 185 } | 200 } |
| 186 | 201 |
| 187 TransportDIB* ImageDataPlatformBackend::GetTransportDIB() const { | 202 TransportDIB* ImageDataPlatformBackend::GetTransportDIB() const { |
| 188 return dib_.get(); | 203 return dib_.get(); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 return skia_canvas_.get(); | 323 return skia_canvas_.get(); |
| 309 } | 324 } |
| 310 | 325 |
| 311 const SkBitmap* ImageDataSimpleBackend::GetMappedBitmap() const { | 326 const SkBitmap* ImageDataSimpleBackend::GetMappedBitmap() const { |
| 312 if (!IsMapped()) | 327 if (!IsMapped()) |
| 313 return NULL; | 328 return NULL; |
| 314 return &skia_bitmap_; | 329 return &skia_bitmap_; |
| 315 } | 330 } |
| 316 | 331 |
| 317 } // namespace content | 332 } // namespace content |
| OLD | NEW |