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 16 TransportDIB::TransportDIB() 17 : size_(0) { 18 } 19 20 TransportDIB::~TransportDIB() { 21 } 22 23 TransportDIB::TransportDIB(HANDLE handle) 24 : shared_memory_(handle, false /* read write */), 25 size_(0) { 26 } 27 28 // static 29 TransportDIB* 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 44 TransportDIB* 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 52 TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { 53 return new TransportDIB(handle); 54 } 55 56 // static 57 bool TransportDIB::is_valid_handle(Handle dib) { 58 return dib != NULL; 59 } 60 61 // static 62 bool TransportDIB::is_valid_id(TransportDIB::Id id) { 63 return is_valid_handle(id.handle); 64 } 65 66 skia::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 85 bool 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 102 void* TransportDIB::memory() const { 103 return shared_memory_.memory(); 104 } 105 106 TransportDIB::Handle TransportDIB::handle() const { 107 return shared_memory_.handle(); 108 } 109 110 TransportDIB::Id TransportDIB::id() const { 111 return Id(handle(), sequence_num_); 112 } 113