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 #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