1/* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "experimental/graphite/src/DrawContext.h" 9 10#include "include/private/SkColorData.h" 11 12#include "experimental/graphite/src/CommandBuffer.h" 13#include "experimental/graphite/src/DrawList.h" 14#include "experimental/graphite/src/DrawPass.h" 15#include "experimental/graphite/src/RenderPassTask.h" 16#include "experimental/graphite/src/TextureProxy.h" 17#include "experimental/graphite/src/geom/BoundsManager.h" 18#include "experimental/graphite/src/geom/Shape.h" 19 20namespace skgpu { 21 22sk_sp<DrawContext> DrawContext::Make(sk_sp<TextureProxy> target, 23 sk_sp<SkColorSpace> colorSpace, 24 SkColorType colorType, 25 SkAlphaType alphaType) { 26 if (!target) { 27 return nullptr; 28 } 29 30 // TODO: validate that the color type and alpha type are compatible with the target's info 31 SkImageInfo imageInfo = SkImageInfo::Make(target->dimensions(), 32 colorType, 33 alphaType, 34 std::move(colorSpace)); 35 return sk_sp<DrawContext>(new DrawContext(std::move(target), imageInfo)); 36} 37 38DrawContext::DrawContext(sk_sp<TextureProxy> target, const SkImageInfo& ii) 39 : fTarget(std::move(target)) 40 , fImageInfo(ii) 41 , fPendingDraws(std::make_unique<DrawList>()) { 42 // TBD - Will probably want DrawLists (and its internal commands) to come from an arena 43 // that the DC manages. 44} 45 46DrawContext::~DrawContext() { 47 // If the DC is destroyed and there are pending commands, they won't be drawn. 48 fPendingDraws.reset(); 49 fDrawPasses.clear(); 50} 51 52void DrawContext::stencilAndFillPath(const Transform& localToDevice, 53 const Shape& shape, 54 const Clip& clip, 55 DrawOrder order, 56 const PaintParams* paint) { 57 SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(clip.scissor())); 58 fPendingDraws->stencilAndFillPath(localToDevice, shape, clip, order,paint); 59} 60 61void DrawContext::fillConvexPath(const Transform& localToDevice, 62 const Shape& shape, 63 const Clip& clip, 64 DrawOrder order, 65 const PaintParams* paint) { 66 SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(clip.scissor())); 67 fPendingDraws->fillConvexPath(localToDevice, shape, clip, order, paint); 68} 69 70void DrawContext::strokePath(const Transform& localToDevice, 71 const Shape& shape, 72 const StrokeParams& stroke, 73 const Clip& clip, 74 DrawOrder order, 75 const PaintParams* paint) { 76 SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(clip.scissor())); 77 fPendingDraws->strokePath(localToDevice, shape, stroke, clip, order, paint); 78} 79 80void DrawContext::clear(const SkColor4f& clearColor) { 81 fPendingLoadOp = LoadOp::kClear; 82 SkPMColor4f pmColor = clearColor.premul(); 83 fPendingClearColor = pmColor.array(); 84 85 // a fullscreen clear will overwrite anything that came before, so start a new DrawList 86 // and clear any drawpasses that haven't been snapped yet 87 fPendingDraws = std::make_unique<DrawList>(); 88 fDrawPasses.clear(); 89} 90 91void DrawContext::snapDrawPass(Recorder* recorder, const BoundsManager* occlusionCuller) { 92 if (fPendingDraws->drawCount() == 0) { 93 return; 94 } 95 96 auto pass = DrawPass::Make(recorder, std::move(fPendingDraws), fTarget, 97 std::make_pair(fPendingLoadOp, fPendingStoreOp), fPendingClearColor, 98 occlusionCuller); 99 fDrawPasses.push_back(std::move(pass)); 100 fPendingDraws = std::make_unique<DrawList>(); 101 fPendingLoadOp = LoadOp::kLoad; 102 fPendingStoreOp = StoreOp::kStore; 103} 104 105sk_sp<Task> DrawContext::snapRenderPassTask(Recorder* recorder, 106 const BoundsManager* occlusionCuller) { 107 this->snapDrawPass(recorder, occlusionCuller); 108 if (fDrawPasses.empty()) { 109 return nullptr; 110 } 111 112 // TODO: At this point we would determine all the targets used by the drawPasses, 113 // build up the union of them and store them in the RenderPassDesc. However, for 114 // the moment we should have only one drawPass. 115 SkASSERT(fDrawPasses.size() == 1); 116 RenderPassDesc desc; 117 desc.fColorAttachment.fTextureProxy = sk_ref_sp(fDrawPasses[0]->target()); 118 std::tie(desc.fColorAttachment.fLoadOp, desc.fColorAttachment.fStoreOp) = fDrawPasses[0]->ops(); 119 desc.fClearColor = fDrawPasses[0]->clearColor(); 120 121 return RenderPassTask::Make(std::move(fDrawPasses), desc); 122} 123 124} // namespace skgpu 125