Home | History | Annotate | Download | only in surface
      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