Wire up surface from render pass descriptor.

This commit is contained in:
Chinmay Garde 2021-06-06 15:34:52 -07:00 committed by Dan Field
parent a8db4feed1
commit 01da845f16
15 changed files with 178 additions and 96 deletions

View File

@ -7,7 +7,12 @@
namespace impeller {
CommandBuffer::CommandBuffer(id<MTLCommandQueue> queue)
: buffer_([queue commandBuffer]) {}
: buffer_([queue commandBuffer]) {
if (!buffer_) {
return;
}
is_valid_ = true;
}
CommandBuffer::~CommandBuffer() = default;

View File

@ -14,6 +14,8 @@
namespace impeller {
class RenderPassDescriptor;
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format) {
switch (format) {
case PixelFormat::kUnknown:
@ -156,6 +158,21 @@ constexpr MTLLoadAction ToMTLLoadAction(LoadAction action) {
return MTLLoadActionDontCare;
}
constexpr LoadAction FromMTLLoadAction(MTLLoadAction action) {
switch (action) {
case MTLLoadActionDontCare:
return LoadAction::kDontCare;
case MTLLoadActionLoad:
return LoadAction::kLoad;
case MTLLoadActionClear:
return LoadAction::kClear;
default:
break;
}
return LoadAction::kDontCare;
}
constexpr MTLStoreAction ToMTLStoreAction(StoreAction action) {
switch (action) {
case StoreAction::kDontCare:
@ -166,10 +183,24 @@ constexpr MTLStoreAction ToMTLStoreAction(StoreAction action) {
return MTLStoreActionDontCare;
}
constexpr StoreAction FromMTLStoreAction(MTLStoreAction action) {
switch (action) {
case MTLStoreActionDontCare:
return StoreAction::kDontCare;
case MTLStoreActionStore:
return StoreAction::kStore;
default:
break;
}
return StoreAction::kDontCare;
}
constexpr MTLClearColor ToMTLClearColor(const Color& color) {
return MTLClearColorMake(color.red, color.green, color.blue, color.alpha);
}
RenderPassDescriptor FromMTLRenderPassDescriptor(MTLRenderPassDescriptor*);
MTLRenderPipelineColorAttachmentDescriptor*
ToMTLRenderPipelineColorAttachmentDescriptor(
ColorAttachmentDescriptor descriptor);

View File

@ -4,6 +4,10 @@
#include "impeller/compositor/formats_metal.h"
#include <memory>
#include "impeller/compositor/render_pass.h"
namespace impeller {
MTLRenderPipelineColorAttachmentDescriptor*
@ -73,4 +77,69 @@ MTLDepthStencilDescriptor* ToMTLDepthStencilDescriptor(
return des;
}
static bool ConfigureRenderPassAttachment(
RenderPassAttachment& attachment,
MTLRenderPassAttachmentDescriptor* desc) {
if (!attachment) {
return false;
}
if (!desc.texture) {
return false;
}
attachment.texture = std::make_shared<Texture>(desc.texture);
attachment.load_action = FromMTLLoadAction(desc.loadAction);
attachment.store_action = FromMTLStoreAction(desc.storeAction);
return true;
}
static ColorRenderPassAttachment FromMTLRenderPassColorAttachmentDescriptor(
MTLRenderPassColorAttachmentDescriptor* desc) {
ColorRenderPassAttachment attachment;
ConfigureRenderPassAttachment(attachment, desc);
auto clear = desc.clearColor;
attachment.clear_color =
Color{clear.red, clear.green, clear.blue, clear.alpha};
return attachment;
}
static DepthRenderPassAttachment FromMTLRenderPassDepthAttachmentDescriptor(
MTLRenderPassDepthAttachmentDescriptor* desc) {
DepthRenderPassAttachment attachment;
ConfigureRenderPassAttachment(attachment, desc);
attachment.clear_depth = desc.clearDepth;
return attachment;
}
static StencilRenderPassAttachment FromMTLRenderPassStencilAttachmentDescriptor(
MTLRenderPassStencilAttachmentDescriptor* desc) {
StencilRenderPassAttachment attachment;
ConfigureRenderPassAttachment(attachment, desc);
attachment.clear_stencil = desc.clearStencil;
return attachment;
}
RenderPassDescriptor FromMTLRenderPassDescriptor(
MTLRenderPassDescriptor* desc) {
RenderPassDescriptor result;
if (!desc) {
return result;
}
// From https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
constexpr size_t kMaxPossibleColorAttachments = 8u;
for (size_t i = 0; i < kMaxPossibleColorAttachments; i++) {
result.SetColorAttachment(
FromMTLRenderPassColorAttachmentDescriptor(desc.colorAttachments[i]),
i);
}
result.SetDepthAttachment(
FromMTLRenderPassDepthAttachmentDescriptor(desc.depthAttachment));
result.SetStencilAttachment(
FromMTLRenderPassStencilAttachmentDescriptor(desc.stencilAttachment));
return result;
}
} // namespace impeller

View File

@ -43,6 +43,8 @@ class RenderPassDescriptor {
~RenderPassDescriptor();
bool HasColorAttachment(size_t index) const;
RenderPassDescriptor& SetColorAttachment(ColorRenderPassAttachment attachment,
size_t index);

View File

@ -13,6 +13,13 @@ RenderPassDescriptor::RenderPassDescriptor() = default;
RenderPassDescriptor::~RenderPassDescriptor() = default;
bool RenderPassDescriptor::HasColorAttachment(size_t index) const {
if (auto found = colors_.find(index); found != colors_.end()) {
return true;
}
return false;
}
RenderPassDescriptor& RenderPassDescriptor::SetColorAttachment(
ColorRenderPassAttachment attachment,
size_t index) {

View File

@ -4,24 +4,25 @@
#pragma once
#include <dispatch/dispatch.h>
#include <memory>
#include "flutter/fml/macros.h"
#include "impeller/compositor/context.h"
#include "impeller/compositor/surface.h"
#include "impeller/geometry/size.h"
namespace impeller {
class Surface;
class Renderer {
public:
virtual ~Renderer();
bool IsValid() const;
bool SurfaceSizeDidChange(Size size);
bool Render();
bool Render(const Surface& surface);
std::shared_ptr<Context> GetContext() const;
@ -30,16 +31,12 @@ class Renderer {
virtual bool OnRender() = 0;
virtual bool OnSurfaceSizeDidChange(Size size) = 0;
private:
dispatch_semaphore_t frames_in_flight_sema_ = nullptr;
std::shared_ptr<Context> context_;
std::unique_ptr<Surface> surface_;
Size size_;
bool is_valid_ = false;
bool ShouldRender() const;
FML_DISALLOW_COPY_AND_ASSIGN(Renderer);
};

View File

@ -5,17 +5,17 @@
#include "impeller/compositor/renderer.h"
#include "flutter/fml/logging.h"
#include "impeller/compositor/command_buffer.h"
#include "impeller/compositor/surface.h"
namespace impeller {
Renderer::Renderer(std::string shaders_directory)
: context_(std::make_shared<Context>(std::move(shaders_directory))),
surface_(std::make_unique<Surface>(context_)) {
if (!context_->IsValid()) {
return;
}
constexpr size_t kMaxFramesInFlight = 3u;
if (!surface_->IsValid()) {
Renderer::Renderer(std::string shaders_directory)
: frames_in_flight_sema_(::dispatch_semaphore_create(kMaxFramesInFlight)),
context_(std::make_shared<Context>(std::move(shaders_directory))) {
if (!context_->IsValid()) {
return;
}
@ -28,26 +28,28 @@ bool Renderer::IsValid() const {
return is_valid_;
}
bool Renderer::ShouldRender() const {
return IsValid() && !size_.IsZero();
}
bool Renderer::SurfaceSizeDidChange(Size size) {
if (size_ == size) {
return true;
}
size_ = size;
return OnSurfaceSizeDidChange(size_);
}
bool Renderer::Render() {
if (!ShouldRender()) {
bool Renderer::Render(const Surface& surface) {
if (!IsValid()) {
return false;
}
return surface_->Render();
if (!surface.IsValid()) {
return false;
}
auto command_buffer = context_->CreateRenderCommandBuffer();
if (!command_buffer) {
return false;
}
::dispatch_semaphore_wait(frames_in_flight_sema_, DISPATCH_TIME_FOREVER);
command_buffer->Commit(
[sema = frames_in_flight_sema_](CommandBuffer::CommitResult) {
::dispatch_semaphore_signal(sema);
});
return true;
}
std::shared_ptr<Context> Renderer::GetContext() const {

View File

@ -4,28 +4,26 @@
#pragma once
#include <dispatch/dispatch.h>
#include <Metal/Metal.h>
#include <memory>
#include "flutter/fml/macros.h"
#include "impeller/compositor/context.h"
#include "impeller/compositor/render_pass.h"
namespace impeller {
class Surface {
public:
Surface(std::shared_ptr<Context> context);
Surface(RenderPassDescriptor desc);
~Surface();
bool IsValid() const;
bool Render() const;
private:
std::shared_ptr<Context> context_;
dispatch_semaphore_t frames_in_flight_sema_ = nullptr;
RenderPassDescriptor desc_;
bool is_valid_ = false;
FML_DISALLOW_COPY_AND_ASSIGN(Surface);

View File

@ -5,19 +5,13 @@
#include "impeller/compositor/surface.h"
#include "flutter/fml/logging.h"
#include "impeller/compositor/command_buffer.h"
namespace impeller {
constexpr size_t kMaxFramesInFlight = 3u;
Surface::Surface(std::shared_ptr<Context> context)
: context_(std::move(context)),
frames_in_flight_sema_(::dispatch_semaphore_create(kMaxFramesInFlight)) {
if (!context_ || !context_->IsValid()) {
Surface::Surface(RenderPassDescriptor desc) {
if (desc.HasColorAttachment(0)) {
return;
}
is_valid_ = true;
}
@ -27,25 +21,4 @@ bool Surface::IsValid() const {
return is_valid_;
}
bool Surface::Render() const {
if (!IsValid()) {
return false;
}
auto command_buffer = context_->CreateRenderCommandBuffer();
if (!command_buffer) {
return false;
}
::dispatch_semaphore_wait(frames_in_flight_sema_, DISPATCH_TIME_FOREVER);
command_buffer->Commit(
[sema = frames_in_flight_sema_](CommandBuffer::CommitResult) {
::dispatch_semaphore_signal(sema);
});
return true;
}
} // namespace impeller

View File

@ -12,7 +12,7 @@ namespace impeller {
class Texture {
public:
Texture();
Texture(id<MTLTexture> texture);
~Texture();

View File

@ -6,7 +6,7 @@
namespace impeller {
Texture::Texture() = default;
Texture::Texture(id<MTLTexture> texture) : texture_(texture) {}
Texture::~Texture() = default;

View File

@ -21,8 +21,6 @@ class EntityRenderer final : public Renderer {
bool OnRender() override;
bool OnSurfaceSizeDidChange(Size size) override;
FML_DISALLOW_COPY_AND_ASSIGN(EntityRenderer);
};

View File

@ -8,7 +8,9 @@ namespace impeller {
EntityRenderer::EntityRenderer(std::string shaders_directory)
: Renderer(std::move(shaders_directory)),
root_(std::make_shared<Entity>()) {}
root_(std::make_shared<Entity>()) {
root_->SetBackgroundColor(Color::DarkGray());
}
EntityRenderer::~EntityRenderer() = default;
@ -16,8 +18,4 @@ bool EntityRenderer::OnRender() {
return false;
}
bool EntityRenderer::OnSurfaceSizeDidChange(Size size) {
return false;
}
} // namespace impeller

View File

@ -12,41 +12,45 @@ struct Size {
double width = 0.0;
double height = 0.0;
Size() {}
constexpr Size() {}
Size(double width, double height) : width(width), height(height) {}
constexpr Size(double width, double height) : width(width), height(height) {}
/*
* Operator overloads
*/
Size operator*(double scale) const { return {width * scale, height * scale}; }
constexpr Size operator*(double scale) const {
return {width * scale, height * scale};
}
bool operator==(const Size& s) const {
constexpr bool operator==(const Size& s) const {
return s.width == width && s.height == height;
}
bool operator!=(const Size& s) const {
constexpr bool operator!=(const Size& s) const {
return s.width != width || s.height != height;
}
Size operator+(const Size& s) const {
constexpr Size operator+(const Size& s) const {
return {width + s.width, height + s.height};
}
Size operator-(const Size& s) const {
constexpr Size operator-(const Size& s) const {
return {width - s.width, height - s.height};
}
Size Union(const Size& o) const {
constexpr Size Union(const Size& o) const {
return {
std::max(width, o.width),
std::max(height, o.height),
};
}
bool IsZero() const { return width * height == 0.0; }
constexpr bool IsZero() const { return width * height == 0.0; }
bool IsPositive() const { return width > 0.0 && height > 0.0; }
constexpr bool IsPositive() const { return width * height > 0.0; }
constexpr bool IsEmpty() { return !IsPositive(); }
std::string ToString() const;

View File

@ -8,6 +8,8 @@
#include "assets_location.h"
#include "flutter/fml/logging.h"
#include "impeller/compositor/formats_metal.h"
#include "impeller/compositor/surface.h"
#include "impeller/entity/entity_renderer.h"
#include "impeller/primitives/box_primitive.h"
#include "impeller_renderer.h"
@ -53,11 +55,7 @@ static const size_t kAlignedUniformsSize = (sizeof(Uniforms) & ~0xFF) + 0x100;
renderer_ = std::make_unique<impeller::EntityRenderer>(
impeller::ImpellerShadersDirectory());
if (!renderer_->IsValid()) {
FML_LOG(ERROR) << "Impeller Renderer is not valid.";
}
FML_CHECK(renderer_->IsValid()) << "Impeller Renderer is not valid.";
return self;
}
@ -227,7 +225,9 @@ static const size_t kAlignedUniformsSize = (sizeof(Uniforms) & ~0xFF) + 0x100;
}
- (void)drawInMTKView:(nonnull MTKView*)view {
if (!renderer_->Render()) {
impeller::Surface surface(
impeller::FromMTLRenderPassDescriptor(view.currentRenderPassDescriptor));
if (!renderer_->Render(surface)) {
FML_LOG(ERROR) << "Could not render.";
}
/// Per frame updates here
@ -304,8 +304,6 @@ static const size_t kAlignedUniformsSize = (sizeof(Uniforms) & ~0xFF) + 0x100;
}
- (void)mtkView:(nonnull MTKView*)view drawableSizeWillChange:(CGSize)size {
renderer_->SurfaceSizeDidChange({size.width, size.height});
float aspect = size.width / (float)size.height;
_projectionMatrix = matrix_perspective_right_hand(65.0f * (M_PI / 180.0f),
aspect, 0.1f, 100.0f);