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 // Desktop GTK Linux builds use the old-style SYSV SHM based DIBs. 8 #if !defined(TOOLKIT_GTK) 9 10 #include <sys/stat.h> 11 #include <unistd.h> 12 13 #include "base/logging.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/shared_memory.h" 16 #include "base/posix/eintr_wrapper.h" 17 #include "skia/ext/platform_canvas.h" 18 19 TransportDIB::TransportDIB() 20 : size_(0) { 21 } 22 23 TransportDIB::TransportDIB(TransportDIB::Handle dib) 24 : shared_memory_(dib, false /* read write */), 25 size_(0) { 26 } 27 28 TransportDIB::~TransportDIB() { 29 } 30 31 // static 32 TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { 33 TransportDIB* dib = new TransportDIB; 34 if (!dib->shared_memory_.CreateAndMapAnonymous(size)) { 35 delete dib; 36 return NULL; 37 } 38 39 dib->size_ = size; 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.fd >= 0; 59 } 60 61 // static 62 bool TransportDIB::is_valid_id(Id id) { 63 #if defined(OS_ANDROID) 64 return is_valid_handle(id); 65 #else 66 return id != 0; 67 #endif 68 } 69 70 skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { 71 if ((!memory() && !Map()) || !VerifyCanvasSize(w, h)) 72 return NULL; 73 return skia::CreatePlatformCanvas(w, h, true, 74 reinterpret_cast<uint8_t*>(memory()), 75 skia::RETURN_NULL_ON_FAILURE); 76 } 77 78 bool TransportDIB::Map() { 79 if (!is_valid_handle(handle())) 80 return false; 81 #if defined(OS_ANDROID) 82 if (!shared_memory_.Map(0)) 83 return false; 84 size_ = shared_memory_.mapped_size(); 85 #else 86 if (memory()) 87 return true; 88 89 struct stat st; 90 if ((fstat(shared_memory_.handle().fd, &st) != 0) || 91 (!shared_memory_.Map(st.st_size))) { 92 return false; 93 } 94 95 size_ = st.st_size; 96 #endif 97 return true; 98 } 99 100 void* TransportDIB::memory() const { 101 return shared_memory_.memory(); 102 } 103 104 TransportDIB::Id TransportDIB::id() const { 105 #if defined(OS_ANDROID) 106 return handle(); 107 #else 108 return shared_memory_.id(); 109 #endif 110 } 111 112 TransportDIB::Handle TransportDIB::handle() const { 113 return shared_memory_.handle(); 114 } 115 116 #endif // !defined(TOOLKIT_GTK) 117 118