// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/gl/gl_image_shared_memory.h" #include "base/logging.h" #include "base/numerics/safe_math.h" #include "base/process/process_handle.h" namespace gfx { namespace { // Returns true if the size is valid and false otherwise. bool SizeInBytes(const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, size_t* size_in_bytes) { if (size.IsEmpty()) return false; size_t stride_in_bytes = 0; if (!GLImageMemory::StrideInBytes(size.width(), format, &stride_in_bytes)) return false; base::CheckedNumeric s = stride_in_bytes; s *= size.height(); if (!s.IsValid()) return false; *size_in_bytes = s.ValueOrDie(); return true; } } // namespace GLImageSharedMemory::GLImageSharedMemory(const gfx::Size& size, unsigned internalformat) : GLImageMemory(size, internalformat) { } GLImageSharedMemory::~GLImageSharedMemory() { DCHECK(!shared_memory_); } bool GLImageSharedMemory::Initialize(const gfx::GpuMemoryBufferHandle& handle, gfx::GpuMemoryBuffer::Format format) { size_t size_in_bytes; if (!SizeInBytes(GetSize(), format, &size_in_bytes)) return false; if (!base::SharedMemory::IsHandleValid(handle.handle)) return false; base::SharedMemory shared_memory(handle.handle, true); // Duplicate the handle. base::SharedMemoryHandle duped_shared_memory_handle; if (!shared_memory.ShareToProcess(base::GetCurrentProcessHandle(), &duped_shared_memory_handle)) { DVLOG(0) << "Failed to duplicate shared memory handle."; return false; } scoped_ptr duped_shared_memory( new base::SharedMemory(duped_shared_memory_handle, true)); if (!duped_shared_memory->Map(size_in_bytes)) { DVLOG(0) << "Failed to map shared memory."; return false; } if (!GLImageMemory::Initialize( static_cast(duped_shared_memory->memory()), format)) { return false; } DCHECK(!shared_memory_); shared_memory_ = duped_shared_memory.Pass(); return true; } void GLImageSharedMemory::Destroy(bool have_context) { GLImageMemory::Destroy(have_context); shared_memory_.reset(); } } // namespace gfx