15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/surface/transport_dib.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/shared_memory.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB::TransportDIB()
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : size_(0) {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB::TransportDIB(TransportDIB::Handle dib)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : shared_memory_(dib, false /* read write */),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_(0) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB::~TransportDIB() {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportDIB* dib = new TransportDIB;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dib->shared_memory_.CreateAndMapAnonymous(size)) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete dib;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dib->size_ = size;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dib;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB* TransportDIB::Map(Handle handle) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TransportDIB> dib(CreateWithHandle(handle));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dib->Map())
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dib.release();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB* TransportDIB::CreateWithHandle(Handle handle) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new TransportDIB(handle);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TransportDIB::is_valid_handle(Handle dib) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dib.fd >= 0;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TransportDIB::is_valid_id(Id id) {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return is_valid_handle(id);
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id != 0;
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if ((!memory() && !Map()) || !VerifyCanvasSize(w, h))
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return skia::CreatePlatformCanvas(w, h, true,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    reinterpret_cast<uint8_t*>(memory()),
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    skia::RETURN_NULL_ON_FAILURE);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TransportDIB::Map() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid_handle(handle()))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!shared_memory_.Map(0))
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_ = shared_memory_.mapped_size();
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (memory())
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct stat st;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((fstat(shared_memory_.handle().fd, &st) != 0) ||
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (!shared_memory_.Map(st.st_size))) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_ = st.st_size;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* TransportDIB::memory() const {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_.memory();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB::Id TransportDIB::id() const {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return handle();
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_.id();
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB::Handle TransportDIB::handle() const {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_.handle();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
111