#ifndef CONTENT_RENDERER_PEPPER_PPB_IMAGE_DATA_IMPL_H_
#define CONTENT_RENDERER_PEPPER_PPB_IMAGE_DATA_IMPL_H_
#include <stdint.h>
#include <memory>
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "ppapi/c/ppb_image_data.h"
#include "ppapi/shared_impl/ppb_image_data_shared.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/ppb_image_data_api.h"
#include "third_party/skia/include/core/SkBitmap.h"
class SkCanvas;
class TransportDIB;
namespace content {
class PPB_ImageData_Impl : public ppapi::Resource,
public ppapi::PPB_ImageData_Shared,
public ppapi::thunk::PPB_ImageData_API {
public:
class Backend {
public:
virtual ~Backend() {}
virtual bool Init(PPB_ImageData_Impl* impl,
PP_ImageDataFormat format,
int width,
int height,
bool init_to_zero) = 0;
virtual bool IsMapped() const = 0;
virtual TransportDIB* GetTransportDIB() const = 0;
virtual void* Map() = 0;
virtual void Unmap() = 0;
virtual int32_t GetSharedMemoryRegion(
base::UnsafeSharedMemoryRegion** region) = 0;
virtual SkCanvas* GetCanvas() = 0;
virtual SkBitmap GetMappedBitmap() const = 0;
};
PPB_ImageData_Impl(PP_Instance instance,
PPB_ImageData_Shared::ImageDataType type);
PPB_ImageData_Impl(const PPB_ImageData_Impl&) = delete;
PPB_ImageData_Impl& operator=(const PPB_ImageData_Impl&) = delete;
struct ForTest {};
PPB_ImageData_Impl(PP_Instance instance, ForTest);
bool Init(PP_ImageDataFormat format,
int width,
int height,
bool init_to_zero);
static PP_Resource Create(PP_Instance pp_instance,
PPB_ImageData_Shared::ImageDataType type,
PP_ImageDataFormat format,
const PP_Size& size,
PP_Bool init_to_zero);
int width() const { return width_; }
int height() const { return height_; }
PP_ImageDataFormat format() const { return format_; }
bool IsMapped() const;
TransportDIB* GetTransportDIB() const;
ppapi::thunk::PPB_ImageData_API* AsPPB_ImageData_API() override;
PP_Bool Describe(PP_ImageDataDesc* desc) override;
void* Map() override;
void Unmap() override;
int32_t GetSharedMemoryRegion(
base::UnsafeSharedMemoryRegion** region) override;
SkCanvas* GetCanvas() override;
void SetIsCandidateForReuse() override;
SkBitmap GetMappedBitmap() const;
private:
~PPB_ImageData_Impl() override;
PP_ImageDataFormat format_;
int width_;
int height_;
std::unique_ptr<Backend> backend_;
};
class ImageDataPlatformBackend : public PPB_ImageData_Impl::Backend {
public:
ImageDataPlatformBackend();
ImageDataPlatformBackend(const ImageDataPlatformBackend&) = delete;
ImageDataPlatformBackend& operator=(const ImageDataPlatformBackend&) = delete;
~ImageDataPlatformBackend() override;
bool Init(PPB_ImageData_Impl* impl,
PP_ImageDataFormat format,
int width,
int height,
bool init_to_zero) override;
bool IsMapped() const override;
TransportDIB* GetTransportDIB() const override;
void* Map() override;
void Unmap() override;
int32_t GetSharedMemoryRegion(
base::UnsafeSharedMemoryRegion** region) override;
SkCanvas* GetCanvas() override;
SkBitmap GetMappedBitmap() const override;
private:
int width_;
int height_;
std::unique_ptr<TransportDIB> dib_;
std::unique_ptr<SkCanvas> mapped_canvas_;
};
class ImageDataSimpleBackend : public PPB_ImageData_Impl::Backend {
public:
ImageDataSimpleBackend();
ImageDataSimpleBackend(const ImageDataSimpleBackend&) = delete;
ImageDataSimpleBackend& operator=(const ImageDataSimpleBackend&) = delete;
~ImageDataSimpleBackend() override;
bool Init(PPB_ImageData_Impl* impl,
PP_ImageDataFormat format,
int width,
int height,
bool init_to_zero) override;
bool IsMapped() const override;
TransportDIB* GetTransportDIB() const override;
void* Map() override;
void Unmap() override;
int32_t GetSharedMemoryRegion(
base::UnsafeSharedMemoryRegion** region) override;
SkCanvas* GetCanvas() override;
SkBitmap GetMappedBitmap() const override;
private:
base::UnsafeSharedMemoryRegion shm_region_;
base::WritableSharedMemoryMapping shm_mapping_;
SkBitmap skia_bitmap_;
std::unique_ptr<SkCanvas> skia_canvas_;
uint32_t map_count_;
};
class ImageDataAutoMapper {
public:
explicit ImageDataAutoMapper(PPB_ImageData_Impl* image_data)
: image_data_(image_data) {
if (image_data_->IsMapped()) {
is_valid_ = true;
needs_unmap_ = false;
} else {
is_valid_ = needs_unmap_ = !!image_data_->Map();
}
}
ImageDataAutoMapper(const ImageDataAutoMapper&) = delete;
ImageDataAutoMapper& operator=(const ImageDataAutoMapper&) = delete;
~ImageDataAutoMapper() {
if (needs_unmap_)
image_data_->Unmap();
}
bool is_valid() const { return is_valid_; }
private:
PPB_ImageData_Impl* image_data_;
bool is_valid_;
bool needs_unmap_;
};
}
#endif