Commit 6cc873cc authored by Vasiliy Telezhnikov's avatar Vasiliy Telezhnikov Committed by Commit Bot

Implement CreateSharedImage with data for AHB

This CL adds implementation to CreateSharedImage overload with
|pixel_data| to SharedImageBackingFactoryAHB.

Bug: 1002057
Change-Id: I246284c6df5f75c25bbedd69658d4fdfaac0f9b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1792579
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695759}
parent 3a4c7507
...@@ -128,7 +128,8 @@ class SharedImageBackingAHB : public SharedImageBacking { ...@@ -128,7 +128,8 @@ class SharedImageBackingAHB : public SharedImageBacking {
uint32_t usage, uint32_t usage,
base::android::ScopedHardwareBufferHandle handle, base::android::ScopedHardwareBufferHandle handle,
size_t estimated_size, size_t estimated_size,
bool is_thread_safe); bool is_thread_safe,
base::ScopedFD initial_upload_fd);
~SharedImageBackingAHB() override; ~SharedImageBackingAHB() override;
...@@ -439,7 +440,8 @@ SharedImageBackingAHB::SharedImageBackingAHB( ...@@ -439,7 +440,8 @@ SharedImageBackingAHB::SharedImageBackingAHB(
uint32_t usage, uint32_t usage,
base::android::ScopedHardwareBufferHandle handle, base::android::ScopedHardwareBufferHandle handle,
size_t estimated_size, size_t estimated_size,
bool is_thread_safe) bool is_thread_safe,
base::ScopedFD initial_upload_fd)
: SharedImageBacking(mailbox, : SharedImageBacking(mailbox,
format, format,
size, size,
...@@ -447,7 +449,8 @@ SharedImageBackingAHB::SharedImageBackingAHB( ...@@ -447,7 +449,8 @@ SharedImageBackingAHB::SharedImageBackingAHB(
usage, usage,
estimated_size, estimated_size,
is_thread_safe), is_thread_safe),
hardware_buffer_handle_(std::move(handle)) { hardware_buffer_handle_(std::move(handle)),
write_sync_fd_(std::move(initial_upload_fd)) {
DCHECK(hardware_buffer_handle_.is_valid()); DCHECK(hardware_buffer_handle_.is_valid());
} }
...@@ -814,15 +817,16 @@ bool SharedImageBackingFactoryAHB::ValidateUsage( ...@@ -814,15 +817,16 @@ bool SharedImageBackingFactoryAHB::ValidateUsage(
return true; return true;
} }
std::unique_ptr<SharedImageBacking> std::unique_ptr<SharedImageBacking> SharedImageBackingFactoryAHB::MakeBacking(
SharedImageBackingFactoryAHB::CreateSharedImage(
const Mailbox& mailbox, const Mailbox& mailbox,
viz::ResourceFormat format, viz::ResourceFormat format,
const gfx::Size& size, const gfx::Size& size,
const gfx::ColorSpace& color_space, const gfx::ColorSpace& color_space,
uint32_t usage, uint32_t usage,
bool is_thread_safe) { bool is_thread_safe,
base::span<const uint8_t> pixel_data) {
DCHECK(base::AndroidHardwareBufferCompat::IsSupportAvailable()); DCHECK(base::AndroidHardwareBufferCompat::IsSupportAvailable());
DCHECK(format != viz::ETC1);
if (!ValidateUsage(usage, size, format)) { if (!ValidateUsage(usage, size, format)) {
return nullptr; return nullptr;
...@@ -852,6 +856,10 @@ SharedImageBackingFactoryAHB::CreateSharedImage( ...@@ -852,6 +856,10 @@ SharedImageBackingFactoryAHB::CreateSharedImage(
if (usage & SHARED_IMAGE_USAGE_SCANOUT) if (usage & SHARED_IMAGE_USAGE_SCANOUT)
hwb_desc.usage |= gl::SurfaceControl::RequiredUsage(); hwb_desc.usage |= gl::SurfaceControl::RequiredUsage();
// Add WRITE usage as we'll it need to upload data
if (!pixel_data.empty())
hwb_desc.usage |= AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
// Number of images in an image array. // Number of images in an image array.
hwb_desc.layers = 1; hwb_desc.layers = 1;
...@@ -867,13 +875,59 @@ SharedImageBackingFactoryAHB::CreateSharedImage( ...@@ -867,13 +875,59 @@ SharedImageBackingFactoryAHB::CreateSharedImage(
return nullptr; return nullptr;
} }
auto handle = base::android::ScopedHardwareBufferHandle::Adopt(buffer);
base::ScopedFD initial_upload_fd;
// Upload data if necessary
if (!pixel_data.empty()) {
// Get description about buffer to obtain stride
AHardwareBuffer_Desc hwb_info;
base::AndroidHardwareBufferCompat::GetInstance().Describe(buffer,
&hwb_info);
void* address = nullptr;
if (int error = base::AndroidHardwareBufferCompat::GetInstance().Lock(
buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1, 0, &address)) {
LOG(ERROR) << "Failed to lock AHardwareBuffer: " << error;
return nullptr;
}
int bytes_per_pixel = BitsPerPixel(format) / 8;
// NOTE: hwb_info.stride is in pixels
int dst_stride = bytes_per_pixel * hwb_info.stride;
int src_stride = bytes_per_pixel * size.width();
for (int y = 0; y < size.height(); y++) {
void* dst = reinterpret_cast<uint8_t*>(address) + dst_stride * y;
const void* src = pixel_data.data() + src_stride * y;
memcpy(dst, src, src_stride);
}
int32_t fence = -1;
base::AndroidHardwareBufferCompat::GetInstance().Unlock(buffer, &fence);
initial_upload_fd = base::ScopedFD(fence);
}
auto backing = std::make_unique<SharedImageBackingAHB>( auto backing = std::make_unique<SharedImageBackingAHB>(
mailbox, format, size, color_space, usage, mailbox, format, size, color_space, usage, std::move(handle),
base::android::ScopedHardwareBufferHandle::Adopt(buffer), estimated_size, estimated_size, is_thread_safe, std::move(initial_upload_fd));
is_thread_safe);
return backing; return backing;
} }
std::unique_ptr<SharedImageBacking>
SharedImageBackingFactoryAHB::CreateSharedImage(
const Mailbox& mailbox,
viz::ResourceFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage,
bool is_thread_safe) {
return MakeBacking(mailbox, format, size, color_space, usage, is_thread_safe,
base::span<uint8_t>());
}
std::unique_ptr<SharedImageBacking> std::unique_ptr<SharedImageBacking>
SharedImageBackingFactoryAHB::CreateSharedImage( SharedImageBackingFactoryAHB::CreateSharedImage(
const Mailbox& mailbox, const Mailbox& mailbox,
...@@ -882,8 +936,11 @@ SharedImageBackingFactoryAHB::CreateSharedImage( ...@@ -882,8 +936,11 @@ SharedImageBackingFactoryAHB::CreateSharedImage(
const gfx::ColorSpace& color_space, const gfx::ColorSpace& color_space,
uint32_t usage, uint32_t usage,
base::span<const uint8_t> pixel_data) { base::span<const uint8_t> pixel_data) {
NOTIMPLEMENTED(); auto backing =
return nullptr; MakeBacking(mailbox, format, size, color_space, usage, false, pixel_data);
if (backing)
backing->OnWriteSucceeded();
return backing;
} }
bool SharedImageBackingFactoryAHB::CanImportGpuMemoryBuffer( bool SharedImageBackingFactoryAHB::CanImportGpuMemoryBuffer(
...@@ -925,7 +982,8 @@ SharedImageBackingFactoryAHB::CreateSharedImage( ...@@ -925,7 +982,8 @@ SharedImageBackingFactoryAHB::CreateSharedImage(
return std::make_unique<SharedImageBackingAHB>( return std::make_unique<SharedImageBackingAHB>(
mailbox, resource_format, size, color_space, usage, mailbox, resource_format, size, color_space, usage,
std::move(handle.android_hardware_buffer), estimated_size, false); std::move(handle.android_hardware_buffer), estimated_size, false,
base::ScopedFD());
} }
} // namespace gpu } // namespace gpu
...@@ -63,6 +63,15 @@ class GPU_GLES2_EXPORT SharedImageBackingFactoryAHB ...@@ -63,6 +63,15 @@ class GPU_GLES2_EXPORT SharedImageBackingFactoryAHB
const gfx::Size& size, const gfx::Size& size,
viz::ResourceFormat format) const; viz::ResourceFormat format) const;
std::unique_ptr<SharedImageBacking> MakeBacking(
const Mailbox& mailbox,
viz::ResourceFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage,
bool is_thread_safe,
base::span<const uint8_t> pixel_data);
struct FormatInfo { struct FormatInfo {
FormatInfo(); FormatInfo();
~FormatInfo(); ~FormatInfo();
......
...@@ -73,6 +73,47 @@ class SharedImageBackingFactoryAHBTest : public testing::Test { ...@@ -73,6 +73,47 @@ class SharedImageBackingFactoryAHBTest : public testing::Test {
GrContext* gr_context() { return context_state_->gr_context(); } GrContext* gr_context() { return context_state_->gr_context(); }
std::vector<uint8_t> ReadPixels(Mailbox mailbox, gfx::Size size) {
auto skia_representation =
shared_image_representation_factory_->ProduceSkia(mailbox,
context_state_.get());
EXPECT_TRUE(skia_representation);
std::vector<GrBackendSemaphore> begin_semaphores;
std::vector<GrBackendSemaphore> end_semaphores;
base::Optional<SharedImageRepresentationSkia::ScopedReadAccess>
scoped_read_access;
scoped_read_access.emplace(skia_representation.get(), &begin_semaphores,
&end_semaphores);
auto* promise_texture = scoped_read_access->promise_image_texture();
EXPECT_EQ(0u, begin_semaphores.size());
EXPECT_EQ(0u, end_semaphores.size());
EXPECT_TRUE(promise_texture);
GrBackendTexture backend_texture = promise_texture->backendTexture();
EXPECT_TRUE(backend_texture.isValid());
EXPECT_EQ(size.width(), backend_texture.width());
EXPECT_EQ(size.height(), backend_texture.height());
// Create an Sk Image from GrBackendTexture.
auto sk_image = SkImage::MakeFromTexture(
gr_context(), promise_texture->backendTexture(),
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType,
nullptr);
SkImageInfo dst_info =
SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr);
const int num_pixels = size.width() * size.height();
std::vector<uint8_t> dst_pixels(num_pixels * 4);
// Read back pixels from Sk Image.
EXPECT_TRUE(sk_image->readPixels(dst_info, dst_pixels.data(),
dst_info.minRowBytes(), 0, 0));
scoped_read_access.reset();
return dst_pixels;
}
protected: protected:
scoped_refptr<gl::GLSurface> surface_; scoped_refptr<gl::GLSurface> surface_;
scoped_refptr<gl::GLContext> context_; scoped_refptr<gl::GLContext> context_;
...@@ -197,41 +238,7 @@ TEST_F(SharedImageBackingFactoryAHBTest, GLSkiaGL) { ...@@ -197,41 +238,7 @@ TEST_F(SharedImageBackingFactoryAHBTest, GLSkiaGL) {
api->glClearFn(GL_COLOR_BUFFER_BIT); api->glClearFn(GL_COLOR_BUFFER_BIT);
gl_representation.reset(); gl_representation.reset();
// Next create a SharedImageRepresentationSkia to read back the texture data. auto dst_pixels = ReadPixels(mailbox, size);
auto skia_representation = shared_image_representation_factory_->ProduceSkia(
mailbox, context_state_.get());
EXPECT_TRUE(skia_representation);
std::vector<GrBackendSemaphore> begin_semaphores;
std::vector<GrBackendSemaphore> end_semaphores;
base::Optional<SharedImageRepresentationSkia::ScopedReadAccess>
scoped_read_access;
scoped_read_access.emplace(skia_representation.get(), &begin_semaphores,
&end_semaphores);
auto* promise_texture = scoped_read_access->promise_image_texture();
EXPECT_EQ(0u, begin_semaphores.size());
EXPECT_EQ(0u, end_semaphores.size());
EXPECT_TRUE(promise_texture);
GrBackendTexture backend_texture = promise_texture->backendTexture();
EXPECT_TRUE(backend_texture.isValid());
EXPECT_EQ(size.width(), backend_texture.width());
EXPECT_EQ(size.height(), backend_texture.height());
// Create an Sk Image from GrBackendTexture.
auto sk_image = SkImage::MakeFromTexture(
gr_context(), promise_texture->backendTexture(), kTopLeft_GrSurfaceOrigin,
kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr);
SkImageInfo dst_info =
SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr);
const int num_pixels = size.width() * size.height();
std::unique_ptr<uint8_t[]> dst_pixels(new uint8_t[num_pixels * 4]());
// Read back pixels from Sk Image.
EXPECT_TRUE(sk_image->readPixels(dst_info, dst_pixels.get(),
dst_info.minRowBytes(), 0, 0));
scoped_read_access.reset();
// Compare the pixel values. // Compare the pixel values.
EXPECT_EQ(dst_pixels[0], 0); EXPECT_EQ(dst_pixels[0], 0);
...@@ -239,7 +246,40 @@ TEST_F(SharedImageBackingFactoryAHBTest, GLSkiaGL) { ...@@ -239,7 +246,40 @@ TEST_F(SharedImageBackingFactoryAHBTest, GLSkiaGL) {
EXPECT_EQ(dst_pixels[2], 0); EXPECT_EQ(dst_pixels[2], 0);
EXPECT_EQ(dst_pixels[3], 255); EXPECT_EQ(dst_pixels[3], 255);
skia_representation.reset(); factory_ref.reset();
EXPECT_FALSE(mailbox_manager_.ConsumeTexture(mailbox));
}
TEST_F(SharedImageBackingFactoryAHBTest, InitialData) {
if (!base::AndroidHardwareBufferCompat::IsSupportAvailable())
return;
auto mailbox = Mailbox::GenerateForSharedImage();
auto format = viz::ResourceFormat::RGBA_8888;
gfx::Size size(4, 4);
std::vector<uint8_t> initial_data(size.width() * size.height() * 4);
for (size_t i = 0; i < initial_data.size(); i++) {
initial_data[i] = static_cast<uint8_t>(i);
}
auto color_space = gfx::ColorSpace::CreateSRGB();
uint32_t usage = SHARED_IMAGE_USAGE_GLES2 | SHARED_IMAGE_USAGE_DISPLAY;
auto backing = backing_factory_->CreateSharedImage(
mailbox, format, size, color_space, usage, initial_data);
EXPECT_TRUE(backing);
std::unique_ptr<SharedImageRepresentationFactoryRef> factory_ref =
shared_image_manager_.Register(std::move(backing),
memory_type_tracker_.get());
auto dst_pixels = ReadPixels(mailbox, size);
// Compare the pixel values.
DCHECK(dst_pixels.size() == initial_data.size());
EXPECT_EQ(dst_pixels, initial_data);
factory_ref.reset(); factory_ref.reset();
EXPECT_FALSE(mailbox_manager_.ConsumeTexture(mailbox)); EXPECT_FALSE(mailbox_manager_.ConsumeTexture(mailbox));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment