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