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 3// found in the LICENSE file. 4 5#include "ui/surface/transport_dib.h" 6 7#include <windows.h> 8 9#include <limits> 10 11#include "base/logging.h" 12#include "base/memory/scoped_ptr.h" 13#include "base/sys_info.h" 14#include "skia/ext/platform_canvas.h" 15 16TransportDIB::TransportDIB() 17 : size_(0) { 18} 19 20TransportDIB::~TransportDIB() { 21} 22 23TransportDIB::TransportDIB(HANDLE handle) 24 : shared_memory_(handle, false /* read write */), 25 size_(0) { 26} 27 28// static 29TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { 30 TransportDIB* dib = new TransportDIB; 31 32 if (!dib->shared_memory_.CreateAnonymous(size)) { 33 delete dib; 34 return NULL; 35 } 36 37 dib->size_ = size; 38 dib->sequence_num_ = sequence_num; 39 40 return dib; 41} 42 43// static 44TransportDIB* TransportDIB::Map(Handle handle) { 45 scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); 46 if (!dib->Map()) 47 return NULL; 48 return dib.release(); 49} 50 51// static 52TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { 53 return new TransportDIB(handle); 54} 55 56// static 57bool TransportDIB::is_valid_handle(Handle dib) { 58 return dib != NULL; 59} 60 61// static 62bool TransportDIB::is_valid_id(TransportDIB::Id id) { 63 return is_valid_handle(id.handle); 64} 65 66skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { 67 // This DIB already mapped the file into this process, but PlatformCanvas 68 // will map it again. 69 DCHECK(!memory()) << "Mapped file twice in the same process."; 70 71 // We can't check the canvas size before mapping, but it's safe because 72 // Windows will fail to map the section if the dimensions of the canvas 73 // are too large. 74 skia::PlatformCanvas* canvas = 75 skia::CreatePlatformCanvas(w, h, true, handle(), 76 skia::RETURN_NULL_ON_FAILURE); 77 78 // Calculate the size for the memory region backing the canvas. 79 if (canvas) 80 size_ = skia::PlatformCanvasStrideForWidth(w) * h; 81 82 return canvas; 83} 84 85bool TransportDIB::Map() { 86 if (!is_valid_handle(handle())) 87 return false; 88 if (memory()) 89 return true; 90 91 if (!shared_memory_.Map(0 /* map whole shared memory segment */)) { 92 LOG(ERROR) << "Failed to map transport DIB" 93 << " handle:" << shared_memory_.handle() 94 << " error:" << ::GetLastError(); 95 return false; 96 } 97 98 size_ = shared_memory_.mapped_size(); 99 return true; 100} 101 102void* TransportDIB::memory() const { 103 return shared_memory_.memory(); 104} 105 106TransportDIB::Handle TransportDIB::handle() const { 107 return shared_memory_.handle(); 108} 109 110TransportDIB::Id TransportDIB::id() const { 111 return Id(handle(), sequence_num_); 112} 113