blob: 8420931420697ffaf739e52e867358d4e0c0d1a0 [file] [log] [blame]
// Copyright 2013 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 "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
#include "base/numerics/safe_math.h"
#include "ui/gl/gl_bindings.h"
namespace content {
GpuMemoryBufferImplShm::GpuMemoryBufferImplShm(const gfx::Size& size,
unsigned internalformat)
: GpuMemoryBufferImpl(size, internalformat) {}
GpuMemoryBufferImplShm::~GpuMemoryBufferImplShm() {}
// static
void GpuMemoryBufferImplShm::AllocateSharedMemoryForChildProcess(
const gfx::Size& size,
unsigned internalformat,
base::ProcessHandle child_process,
const AllocationCallback& callback) {
DCHECK(IsLayoutSupported(size, internalformat));
gfx::GpuMemoryBufferHandle handle;
base::SharedMemory shared_memory;
if (!shared_memory.CreateAnonymous(size.GetArea() *
BytesPerPixel(internalformat))) {
handle.type = gfx::EMPTY_BUFFER;
return;
}
handle.type = gfx::SHARED_MEMORY_BUFFER;
shared_memory.GiveToProcess(child_process, &handle.handle);
callback.Run(handle);
}
// static
bool GpuMemoryBufferImplShm::IsLayoutSupported(const gfx::Size& size,
unsigned internalformat) {
base::CheckedNumeric<int> buffer_size = size.width();
buffer_size *= size.height();
buffer_size *= BytesPerPixel(internalformat);
return buffer_size.IsValid();
}
// static
bool GpuMemoryBufferImplShm::IsUsageSupported(unsigned usage) {
switch (usage) {
case GL_IMAGE_MAP_CHROMIUM:
return true;
default:
return false;
}
}
// static
bool GpuMemoryBufferImplShm::IsConfigurationSupported(const gfx::Size& size,
unsigned internalformat,
unsigned usage) {
return IsLayoutSupported(size, internalformat) && IsUsageSupported(usage);
}
bool GpuMemoryBufferImplShm::Initialize() {
DCHECK(IsLayoutSupported(size_, internalformat_));
scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
if (!shared_memory->CreateAnonymous(size_.GetArea() *
BytesPerPixel(internalformat_)))
return false;
shared_memory_ = shared_memory.Pass();
DCHECK(!shared_memory_->memory());
return true;
}
bool GpuMemoryBufferImplShm::InitializeFromHandle(
gfx::GpuMemoryBufferHandle handle) {
DCHECK(IsLayoutSupported(size_, internalformat_));
if (!base::SharedMemory::IsHandleValid(handle.handle))
return false;
shared_memory_.reset(new base::SharedMemory(handle.handle, false));
DCHECK(!shared_memory_->memory());
return true;
}
void* GpuMemoryBufferImplShm::Map() {
DCHECK(!mapped_);
if (!shared_memory_->Map(size_.GetArea() * BytesPerPixel(internalformat_)))
return NULL;
mapped_ = true;
return shared_memory_->memory();
}
void GpuMemoryBufferImplShm::Unmap() {
DCHECK(mapped_);
shared_memory_->Unmap();
mapped_ = false;
}
uint32 GpuMemoryBufferImplShm::GetStride() const {
return size_.width() * BytesPerPixel(internalformat_);
}
gfx::GpuMemoryBufferHandle GpuMemoryBufferImplShm::GetHandle() const {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.handle = shared_memory_->handle();
return handle;
}
} // namespace content