mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-05-11 10:20:04 +02:00
refactor: recreate texture only if device orientation is changed
This commit is contained in:
@@ -12,5 +12,5 @@ protocol RenderPass {
|
||||
var label: String { get }
|
||||
var descriptor: MTLRenderPassDescriptor? { get set }
|
||||
func resize(on view: MTKView, to size: CGSize, with renderer: Renderer)
|
||||
func draw(into commandBuffer: MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer)
|
||||
func draw(into commandBuffer: MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ extension Canvas {
|
||||
let graphicContext = canvas.graphicContext
|
||||
self?.graphicContext.object = graphicContext
|
||||
self?.graphicContext.loadStrokes(bounds)
|
||||
context.refreshAllObjects()
|
||||
context.refresh(canvas, mergeChanges: false)
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.state = .loaded
|
||||
}
|
||||
|
||||
@@ -60,17 +60,23 @@ final class Renderer {
|
||||
self.viewPortRenderPass.view = canvasView
|
||||
}
|
||||
|
||||
func resize(on view: MTKView, to size: CGSize) {
|
||||
if !updatesViewPort {
|
||||
photoBackgroundRenderPass.resize(on: view, to: size, with: self)
|
||||
strokeRenderPass.resize(on: view, to: size, with: self)
|
||||
graphicRenderPass.resize(on: view, to: size, with: self)
|
||||
cacheRenderPass.resize(on: view, to: size, with: self)
|
||||
}
|
||||
viewPortRenderPass.resize(on: view, to: size, with: self)
|
||||
func setUpdatesViewPort(_ value: Bool) {
|
||||
updatesViewPort = value
|
||||
}
|
||||
|
||||
func setRedrawsGraphicRender() {
|
||||
redrawsGraphicRender = true
|
||||
}
|
||||
|
||||
func resize(on view: MTKView, to size: CGSize) {
|
||||
photoBackgroundRenderPass.resize(on: view, to: size, with: self)
|
||||
strokeRenderPass.resize(on: view, to: size, with: self)
|
||||
graphicRenderPass.resize(on: view, to: size, with: self)
|
||||
cacheRenderPass.resize(on: view, to: size, with: self)
|
||||
viewPortRenderPass.resize(on: view, to: size, with: self)
|
||||
setRedrawsGraphicRender()
|
||||
}
|
||||
|
||||
func draw(in view: MTKView, on canvas: Canvas) {
|
||||
guard let commandBuffer = commandQueue.makeCommandBuffer() else {
|
||||
NSLog("[Memola] - Unable to create command buffer")
|
||||
@@ -94,6 +100,7 @@ final class Renderer {
|
||||
cacheRenderPass.draw(into: commandBuffer, on: canvas, with: self)
|
||||
|
||||
viewPortRenderPass.descriptor = view.currentRenderPassDescriptor
|
||||
viewPortRenderPass.excludesPhotoBackground = photoBackgroundRenderPass.clearsTexture
|
||||
viewPortRenderPass.photoBackgroundTexture = photoBackgroundRenderPass.photoBackgroundTexture
|
||||
viewPortRenderPass.cacheTexture = cacheRenderPass.cacheTexture
|
||||
viewPortRenderPass.draw(into: commandBuffer, on: canvas, with: self)
|
||||
|
||||
@@ -34,14 +34,15 @@ class CacheRenderPass: RenderPass {
|
||||
cacheTexture = Textures.createCacheTexture(from: renderer, size: size, pixelFormat: view.colorPixelFormat)
|
||||
}
|
||||
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
guard let descriptor else { return }
|
||||
@discardableResult
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool {
|
||||
guard let descriptor else { return false }
|
||||
|
||||
// MARK: - Copying texture
|
||||
guard let graphicTexture, let cacheTexture else { return }
|
||||
guard let cachePipelineState else { return }
|
||||
guard let graphicTexture, let cacheTexture else { return false }
|
||||
guard let cachePipelineState else { return false }
|
||||
guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() else {
|
||||
return
|
||||
return false
|
||||
}
|
||||
computeEncoder.label = "Cache Compute Encoder"
|
||||
|
||||
@@ -58,7 +59,7 @@ class CacheRenderPass: RenderPass {
|
||||
computeEncoder.endEncoding()
|
||||
|
||||
// MARK: - Drawing
|
||||
guard let graphicPipelineState else { return }
|
||||
guard let graphicPipelineState else { return false }
|
||||
descriptor.colorAttachments[0].texture = cacheTexture
|
||||
descriptor.colorAttachments[0].clearColor = MTLClearColor(red: 1, green: 1, blue: 1, alpha: 0)
|
||||
descriptor.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
||||
@@ -67,23 +68,25 @@ class CacheRenderPass: RenderPass {
|
||||
let graphicContext = canvas.graphicContext
|
||||
if let element = graphicContext.currentElement {
|
||||
let elementGroup = ElementGroup(element)
|
||||
var status: Bool?
|
||||
switch elementGroup.type {
|
||||
case .stroke:
|
||||
canvas.setGraphicRenderType(.inProgress)
|
||||
strokeRenderPass?.elementGroup = elementGroup
|
||||
strokeRenderPass?.graphicDescriptor = descriptor
|
||||
strokeRenderPass?.graphicPipelineState = graphicPipelineState
|
||||
strokeRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
status = strokeRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
case .eraser:
|
||||
eraserRenderPass?.elementGroup = elementGroup
|
||||
eraserRenderPass?.descriptor = descriptor
|
||||
eraserRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
status = eraserRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
case .photo:
|
||||
photoRenderPass?.elementGroup = elementGroup
|
||||
photoRenderPass?.descriptor = descriptor
|
||||
photoRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
status = photoRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
}
|
||||
clearsTexture = false
|
||||
clearsTexture = !(status ?? false)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,19 +26,20 @@ class EraserRenderPass: RenderPass {
|
||||
|
||||
func resize(on view: MTKView, to size: CGSize, with renderer: Renderer) { }
|
||||
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
guard let elementGroup else { return }
|
||||
guard let descriptor else { return }
|
||||
@discardableResult
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool {
|
||||
guard let elementGroup else { return false }
|
||||
guard let descriptor else { return false }
|
||||
|
||||
// MARK: - Generating vertices
|
||||
guard !elementGroup.isEmpty, let quadPipelineState else { return }
|
||||
guard !elementGroup.isEmpty, let quadPipelineState else { return false }
|
||||
let eraserStrokes = elementGroup.elements.compactMap { element -> EraserStroke? in
|
||||
guard case .stroke(let anyStroke) = element else { return nil }
|
||||
return anyStroke.value as? EraserStroke
|
||||
}
|
||||
let quads = eraserStrokes.flatMap { $0.quads }
|
||||
guard !quads.isEmpty else { return }
|
||||
guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() else { return }
|
||||
guard !quads.isEmpty else { return false }
|
||||
guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() else { return false }
|
||||
|
||||
computeEncoder.label = "Quad Compute Encoder"
|
||||
|
||||
@@ -58,10 +59,10 @@ class EraserRenderPass: RenderPass {
|
||||
computeEncoder.endEncoding()
|
||||
|
||||
// MARK: - Rendering eraser
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return }
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return false }
|
||||
renderEncoder.label = "Stroke Render Encoder"
|
||||
|
||||
guard let eraserPipelineState else { return }
|
||||
guard let eraserPipelineState else { return false }
|
||||
renderEncoder.setRenderPipelineState(eraserPipelineState)
|
||||
|
||||
canvas.setUniformsBuffer(device: renderer.device, renderEncoder: renderEncoder)
|
||||
@@ -77,5 +78,6 @@ class EraserRenderPass: RenderPass {
|
||||
)
|
||||
}
|
||||
renderEncoder.endEncoding()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,16 +30,18 @@ class GraphicRenderPass: RenderPass {
|
||||
func resize(on view: MTKView, to size: CGSize, with renderer: Renderer) {
|
||||
guard size != .zero else { return }
|
||||
graphicTexture = Textures.createGraphicTexture(from: renderer, size: size, pixelFormat: view.colorPixelFormat)
|
||||
clearsTexture = true
|
||||
}
|
||||
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
@discardableResult
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool {
|
||||
descriptor?.colorAttachments[0].texture = graphicTexture
|
||||
descriptor?.colorAttachments[0].clearColor = MTLClearColor(red: 1, green: 1, blue: 1, alpha: 0)
|
||||
descriptor?.colorAttachments[0].storeAction = .store
|
||||
|
||||
let graphicContext = canvas.graphicContext
|
||||
if renderer.redrawsGraphicRender {
|
||||
clearsTexture = true
|
||||
photoBackgroundRenderPass?.clearsTexture = true
|
||||
canvas.setGraphicRenderType(.finished)
|
||||
var elementGroup: ElementGroup?
|
||||
let start = Date.now.timeIntervalSince1970 * 1000
|
||||
@@ -51,7 +53,7 @@ class GraphicRenderPass: RenderPass {
|
||||
let _elementGroup = ElementGroup(_element)
|
||||
elementGroup = _elementGroup
|
||||
} else {
|
||||
guard let _elementGroup = elementGroup else { return }
|
||||
guard let _elementGroup = elementGroup else { continue }
|
||||
if _elementGroup.isSameElement(_element) {
|
||||
_elementGroup.add(_element)
|
||||
} else {
|
||||
@@ -75,6 +77,7 @@ class GraphicRenderPass: RenderPass {
|
||||
draw(for: elementGroup, into: commandBuffer, on: canvas, with: renderer)
|
||||
graphicContext.previousElement = nil
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func draw(for elementGroup: ElementGroup, into commandBuffer: MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
@@ -84,24 +87,33 @@ class GraphicRenderPass: RenderPass {
|
||||
strokeRenderPass?.elementGroup = elementGroup
|
||||
strokeRenderPass?.graphicDescriptor = descriptor
|
||||
strokeRenderPass?.graphicPipelineState = graphicPipelineState
|
||||
strokeRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
clearsTexture = false
|
||||
let status = strokeRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
if clearsTexture, let status {
|
||||
clearsTexture = !status
|
||||
}
|
||||
case .eraser:
|
||||
descriptor?.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
||||
eraserRenderPass?.elementGroup = elementGroup
|
||||
eraserRenderPass?.descriptor = descriptor
|
||||
eraserRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
clearsTexture = false
|
||||
let status = eraserRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
if clearsTexture, let status {
|
||||
clearsTexture = !status
|
||||
}
|
||||
case .photo:
|
||||
descriptor?.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
||||
photoRenderPass?.elementGroup = elementGroup
|
||||
photoRenderPass?.descriptor = descriptor
|
||||
photoRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
let photoStatus = photoRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
|
||||
photoBackgroundRenderPass?.elementGroup = elementGroup
|
||||
photoBackgroundRenderPass?.clearsTexture = clearsTexture
|
||||
photoBackgroundRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
clearsTexture = false
|
||||
let photoBackgroundStatus = photoBackgroundRenderPass?.draw(into: commandBuffer, on: canvas, with: renderer)
|
||||
|
||||
if clearsTexture, let photoStatus {
|
||||
clearsTexture = !photoStatus
|
||||
}
|
||||
if photoBackgroundRenderPass?.clearsTexture == true, let photoBackgroundStatus {
|
||||
photoBackgroundRenderPass?.clearsTexture = !photoBackgroundStatus
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,30 +27,31 @@ class PhotoBackgroundRenderPass: RenderPass {
|
||||
photoBackgroundPipelineState = PipelineStates.createPhotoPipelineState(from: renderer)
|
||||
}
|
||||
|
||||
func resize(on view: MTKView, to size: CGSize, with renderer: Renderer) {
|
||||
func resize(on view: MTKView, to size: CGSize, with renderer: Renderer) {
|
||||
guard size != .zero else { return }
|
||||
photoBackgroundTexture = Textures.createPhotoBackgroundTexture(from: renderer, size: size, pixelFormat: renderer.pixelFormat)
|
||||
}
|
||||
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
guard let elementGroup else { return }
|
||||
guard let descriptor else { return }
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool {
|
||||
guard let elementGroup else { return false }
|
||||
guard let descriptor else { return false }
|
||||
|
||||
descriptor.colorAttachments[0].texture = photoBackgroundTexture
|
||||
descriptor.colorAttachments[0].storeAction = .store
|
||||
descriptor.colorAttachments[0].loadAction = clearsTexture ? .clear : .load
|
||||
descriptor.colorAttachments[0].clearColor = MTLClearColor(red: 1, green: 1, blue: 1, alpha: 0)
|
||||
|
||||
guard !elementGroup.isEmpty else { return }
|
||||
guard !elementGroup.isEmpty else { return false }
|
||||
|
||||
let photos = elementGroup.elements.compactMap { element -> Photo? in
|
||||
guard case .photo(let photo) = element else { return nil }
|
||||
return photo
|
||||
}
|
||||
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return }
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return false }
|
||||
renderEncoder.label = "Photo Background Render Encoder"
|
||||
|
||||
guard let photoBackgroundPipelineState else { return }
|
||||
guard let photoBackgroundPipelineState else { return false }
|
||||
renderEncoder.setRenderPipelineState(photoBackgroundPipelineState)
|
||||
|
||||
canvas.setUniformsBuffer(device: renderer.device, renderEncoder: renderEncoder)
|
||||
@@ -60,5 +61,6 @@ class PhotoBackgroundRenderPass: RenderPass {
|
||||
}
|
||||
|
||||
renderEncoder.endEncoding()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,21 +24,22 @@ class PhotoRenderPass: RenderPass {
|
||||
|
||||
func resize(on view: MTKView, to size: CGSize, with renderer: Renderer) { }
|
||||
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
guard let elementGroup else { return }
|
||||
guard let descriptor else { return }
|
||||
@discardableResult
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool {
|
||||
guard let elementGroup else { return false }
|
||||
guard let descriptor else { return false }
|
||||
|
||||
guard !elementGroup.isEmpty else { return }
|
||||
guard !elementGroup.isEmpty else { return false }
|
||||
|
||||
let photos = elementGroup.elements.compactMap { element -> Photo? in
|
||||
guard case .photo(let photo) = element else { return nil }
|
||||
return photo
|
||||
}
|
||||
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return }
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return false }
|
||||
renderEncoder.label = "Photo Render Encoder"
|
||||
|
||||
guard let photoPipelineState else { return }
|
||||
guard let photoPipelineState else { return false }
|
||||
renderEncoder.setRenderPipelineState(photoPipelineState)
|
||||
|
||||
canvas.setUniformsBuffer(device: renderer.device, renderEncoder: renderEncoder)
|
||||
@@ -48,5 +49,6 @@ class PhotoRenderPass: RenderPass {
|
||||
}
|
||||
|
||||
renderEncoder.endEncoding()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +34,13 @@ class StrokeRenderPass: RenderPass {
|
||||
strokeTexture = Textures.createStrokeTexture(from: renderer, size: size, pixelFormat: view.colorPixelFormat)
|
||||
}
|
||||
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
guard let elementGroup else { return }
|
||||
guard let descriptor else { return }
|
||||
@discardableResult
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool {
|
||||
guard let elementGroup else { return false }
|
||||
guard let descriptor else { return false }
|
||||
|
||||
// MARK: - Generating vertices
|
||||
guard !elementGroup.isEmpty, let quadPipelineState else { return }
|
||||
guard !elementGroup.isEmpty, let quadPipelineState else { return false }
|
||||
let penStrokes = elementGroup.elements.compactMap { element -> PenStroke? in
|
||||
guard case .stroke(let anyStroke) = element else { return nil }
|
||||
return anyStroke.value as? PenStroke
|
||||
@@ -47,8 +48,8 @@ class StrokeRenderPass: RenderPass {
|
||||
let penStroke = penStrokes.first
|
||||
let quads = penStrokes.flatMap { $0.quads }
|
||||
let erasedQuads = Set(penStrokes.flatMap { $0.eraserStrokes }).flatMap { $0.quads }
|
||||
guard !quads.isEmpty else { return }
|
||||
guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() else { return }
|
||||
guard !quads.isEmpty else { return false }
|
||||
guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() else { return false }
|
||||
|
||||
computeEncoder.label = "Quad Compute Encoder"
|
||||
|
||||
@@ -68,16 +69,16 @@ class StrokeRenderPass: RenderPass {
|
||||
computeEncoder.endEncoding()
|
||||
|
||||
// MARK: - Rendering stroke
|
||||
guard let strokeTexture else { return }
|
||||
guard let strokeTexture else { return false }
|
||||
descriptor.colorAttachments[0].texture = strokeTexture
|
||||
descriptor.colorAttachments[0].clearColor = MTLClearColor(red: 1, green: 1, blue: 1, alpha: 0)
|
||||
descriptor.colorAttachments[0].loadAction = .clear
|
||||
descriptor.colorAttachments[0].storeAction = .store
|
||||
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return }
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return false }
|
||||
renderEncoder.label = "Stroke Render Encoder"
|
||||
|
||||
guard let strokePipelineState else { return }
|
||||
guard let strokePipelineState else { return false }
|
||||
renderEncoder.setRenderPipelineState(strokePipelineState)
|
||||
|
||||
canvas.setUniformsBuffer(device: renderer.device, renderEncoder: renderEncoder)
|
||||
@@ -100,7 +101,7 @@ class StrokeRenderPass: RenderPass {
|
||||
|
||||
// MARK: Erasing path
|
||||
if let eraserPipelineState = eraserRenderPass?.eraserPipelineState, !erasedQuads.isEmpty {
|
||||
guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() else { return }
|
||||
guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() else { return false }
|
||||
|
||||
computeEncoder.label = "Erased Quad Compute Encoder"
|
||||
|
||||
@@ -120,7 +121,7 @@ class StrokeRenderPass: RenderPass {
|
||||
computeEncoder.endEncoding()
|
||||
|
||||
descriptor.colorAttachments[0].loadAction = .load
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return }
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else { return false }
|
||||
renderEncoder.label = "Stroke Eraser Render Encoder"
|
||||
|
||||
renderEncoder.setRenderPipelineState(eraserPipelineState)
|
||||
@@ -140,8 +141,8 @@ class StrokeRenderPass: RenderPass {
|
||||
}
|
||||
|
||||
// MARK: Drawing on graphic texture
|
||||
guard let graphicDescriptor, let graphicPipelineState else { return }
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: graphicDescriptor) else { return }
|
||||
guard let graphicDescriptor, let graphicPipelineState else { return false }
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: graphicDescriptor) else { return false }
|
||||
renderEncoder.label = "Stroke Graphic Render Encoder"
|
||||
renderEncoder.setRenderPipelineState(graphicPipelineState)
|
||||
|
||||
@@ -151,5 +152,7 @@ class StrokeRenderPass: RenderPass {
|
||||
renderEncoder.setVertexBuffer(uniformsBuffer, offset: 0, index: 11)
|
||||
canvas.renderGraphic(device: renderer.device, renderEncoder: renderEncoder)
|
||||
renderEncoder.endEncoding()
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ class ViewPortRenderPass: RenderPass {
|
||||
|
||||
weak var view: MTKView?
|
||||
|
||||
var excludesPhotoBackground: Bool = false
|
||||
|
||||
init(renderer: Renderer) {
|
||||
pointGridPipelineState = PipelineStates.createPointGridPipelineState(from: renderer)
|
||||
lineGridPipelineState = PipelineStates.createLineGridPipelineState(from: renderer)
|
||||
@@ -31,12 +33,13 @@ class ViewPortRenderPass: RenderPass {
|
||||
|
||||
func resize(on view: MTKView, to size: CGSize, with renderer: Renderer) { }
|
||||
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) {
|
||||
@discardableResult
|
||||
func draw(into commandBuffer: any MTLCommandBuffer, on canvas: Canvas, with renderer: Renderer) -> Bool {
|
||||
guard let descriptor else {
|
||||
return
|
||||
return false
|
||||
}
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) else {
|
||||
return
|
||||
return false
|
||||
}
|
||||
renderEncoder.label = "View Port Render Encoder"
|
||||
|
||||
@@ -44,36 +47,40 @@ class ViewPortRenderPass: RenderPass {
|
||||
case .none:
|
||||
break
|
||||
case .point:
|
||||
guard let pointGridPipelineState else { return }
|
||||
guard let pointGridPipelineState else { return false }
|
||||
renderEncoder.setRenderPipelineState(pointGridPipelineState)
|
||||
canvas.renderPointGrid(device: renderer.device, renderEncoder: renderEncoder)
|
||||
case .line:
|
||||
guard let lineGridPipelineState else { return }
|
||||
guard let lineGridPipelineState else { return false }
|
||||
renderEncoder.setRenderPipelineState(lineGridPipelineState)
|
||||
canvas.renderLineGrid(device: renderer.device, renderEncoder: renderEncoder)
|
||||
}
|
||||
|
||||
if renderer.updatesViewPort {
|
||||
guard let viewPortUpdatePipelineState else {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
renderEncoder.setRenderPipelineState(viewPortUpdatePipelineState)
|
||||
|
||||
renderEncoder.setFragmentTexture(photoBackgroundTexture, index: 0)
|
||||
canvas.renderViewPortUpdate(device: renderer.device, renderEncoder: renderEncoder)
|
||||
if !excludesPhotoBackground {
|
||||
renderEncoder.setFragmentTexture(photoBackgroundTexture, index: 0)
|
||||
canvas.renderViewPortUpdate(device: renderer.device, renderEncoder: renderEncoder)
|
||||
}
|
||||
|
||||
renderEncoder.setFragmentTexture(cacheTexture, index: 0)
|
||||
canvas.renderViewPortUpdate(device: renderer.device, renderEncoder: renderEncoder)
|
||||
} else {
|
||||
guard let viewPortPipelineState else {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
renderEncoder.setRenderPipelineState(viewPortPipelineState)
|
||||
|
||||
renderEncoder.setFragmentTexture(photoBackgroundTexture, index: 0)
|
||||
canvas.renderViewPort(device: renderer.device, renderEncoder: renderEncoder)
|
||||
if !excludesPhotoBackground {
|
||||
renderEncoder.setFragmentTexture(photoBackgroundTexture, index: 0)
|
||||
canvas.renderViewPort(device: renderer.device, renderEncoder: renderEncoder)
|
||||
}
|
||||
|
||||
renderEncoder.setFragmentTexture(cacheTexture, index: 0)
|
||||
canvas.renderViewPort(device: renderer.device, renderEncoder: renderEncoder)
|
||||
@@ -82,9 +89,10 @@ class ViewPortRenderPass: RenderPass {
|
||||
renderEncoder.endEncoding()
|
||||
|
||||
guard let drawable = view?.currentDrawable else {
|
||||
return
|
||||
return false
|
||||
}
|
||||
commandBuffer.present(drawable)
|
||||
commandBuffer.commit()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ extension CanvasViewController: UIScrollViewDelegate {
|
||||
|
||||
func scrollViewDidZoom(_ scrollView: UIScrollView) {
|
||||
canvas.setZoomScale(scrollView.zoomScale)
|
||||
renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
// renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
renderView.draw()
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ extension CanvasViewController: UIScrollViewDelegate {
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
// renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
renderView.draw()
|
||||
}
|
||||
|
||||
@@ -302,12 +302,12 @@ extension CanvasViewController {
|
||||
drawingView.touchCancelled()
|
||||
canvas.updateClipBounds(scrollView, on: drawingView)
|
||||
drawingView.disableUserInteraction()
|
||||
renderer.updatesViewPort = true
|
||||
renderer.setUpdatesViewPort(true)
|
||||
}
|
||||
|
||||
func magnificationEnded() {
|
||||
renderer.updatesViewPort = false
|
||||
renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
renderer.setUpdatesViewPort(false)
|
||||
renderer.setRedrawsGraphicRender()
|
||||
renderView.draw()
|
||||
drawingView.enableUserInteraction()
|
||||
}
|
||||
@@ -316,12 +316,12 @@ extension CanvasViewController {
|
||||
guard !renderer.updatesViewPort else { return }
|
||||
canvas.updateClipBounds(scrollView, on: drawingView)
|
||||
drawingView.disableUserInteraction()
|
||||
renderer.updatesViewPort = true
|
||||
renderer.setUpdatesViewPort(true)
|
||||
}
|
||||
|
||||
func draggingEnded() {
|
||||
renderer.updatesViewPort = false
|
||||
renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
renderer.setUpdatesViewPort(false)
|
||||
renderer.setRedrawsGraphicRender()
|
||||
renderView.draw()
|
||||
drawingView.enableUserInteraction()
|
||||
}
|
||||
@@ -371,7 +371,7 @@ extension CanvasViewController {
|
||||
|
||||
func gridModeChanged(_ mode: GridMode) {
|
||||
drawingView.disableUserInteraction()
|
||||
renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
renderer.setRedrawsGraphicRender()
|
||||
renderView.draw()
|
||||
drawingView.enableUserInteraction()
|
||||
}
|
||||
@@ -382,8 +382,7 @@ extension CanvasViewController {
|
||||
guard let event = history.undo() else { return }
|
||||
drawingView.disableUserInteraction()
|
||||
canvas.graphicContext.undoGraphic(for: event)
|
||||
renderer.redrawsGraphicRender = true
|
||||
renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
renderer.setRedrawsGraphicRender()
|
||||
renderView.draw()
|
||||
drawingView.enableUserInteraction()
|
||||
}
|
||||
@@ -392,8 +391,7 @@ extension CanvasViewController {
|
||||
guard let event = history.redo() else { return }
|
||||
drawingView.disableUserInteraction()
|
||||
canvas.graphicContext.redoGraphic(for: event)
|
||||
renderer.redrawsGraphicRender = true
|
||||
renderer.resize(on: renderView, to: renderView.drawableSize)
|
||||
renderer.setRedrawsGraphicRender()
|
||||
renderView.draw()
|
||||
drawingView.enableUserInteraction()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user