TiledPipeController::TiledPipeController(const SkBitmap& bitmap, SkPicture::InstallPixelRefProc proc, const SkMatrix* initial) : INHERITED(NULL, proc) { int32_t top = 0; int32_t bottom; int32_t height = bitmap.height() / NumberOfTiles; SkIRect rect; for (int i = 0; i < NumberOfTiles; i++) { bottom = i + 1 == NumberOfTiles ? bitmap.height() : top + height; rect.setLTRB(0, top, bitmap.width(), bottom); top = bottom; SkDEBUGCODE(bool extracted = )bitmap.extractSubset(&fBitmaps[i], rect); SkASSERT(extracted); SkBaseDevice* device = new SkBitmapDevice(fBitmaps[i]); SkCanvas* canvas = new SkCanvas(device); device->unref(); if (initial != NULL) { canvas->setMatrix(*initial); } canvas->translate(SkIntToScalar(-rect.left()), SkIntToScalar(-rect.top())); if (0 == i) { fReader.setCanvas(canvas); } else { fReaders[i - 1].setCanvas(canvas); fReaders[i - 1].setBitmapDecoder(proc); } canvas->unref(); } }
void GrVkGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) { SkASSERT(!clip.hasWindowRectangles()); CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment(); // this should only be called internally when we know we have a // stencil buffer. SkASSERT(sb); int stencilBitCount = sb->bits(); // The contract with the callers does not guarantee that we preserve all bits in the stencil // during this clear. Thus we will clear the entire stencil to the desired value. VkClearDepthStencilValue vkStencilColor; memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue)); if (insideStencilMask) { vkStencilColor.stencil = (1 << (stencilBitCount - 1)); } else { vkStencilColor.stencil = 0; } VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; if (!clip.scissorEnabled()) { vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) { vkRect = clip.scissorRect(); } else { const SkIRect& scissor = clip.scissorRect(); vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom, scissor.fRight, fRenderTarget->height() - scissor.fTop); } clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; clearRect.baseArrayLayer = 0; clearRect.layerCount = 1; uint32_t stencilIndex; SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex)); VkClearAttachment attachment; attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; attachment.colorAttachment = 0; // this value shouldn't matter attachment.clearValue.depthStencil = vkStencilColor; cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect); cbInfo.fIsEmpty = false; // Update command buffer bounds if (!clip.scissorEnabled()) { cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); } else { cbInfo.fBounds.join(SkRect::Make(clip.scissorRect())); } }
GrTargetCommands::Cmd* GrCommandBuilder::recordClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, GrRenderTarget* renderTarget) { SkASSERT(renderTarget); SkIRect r; if (NULL == rect) { // We could do something smart and remove previous draws and clears to // the current render target. If we get that smart we have to make sure // those draws aren't read before this clear (render-to-texture). r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); rect = &r; } Clear* clr = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), Clear, (renderTarget)); GrColorIsPMAssert(color); clr->fColor = color; clr->fRect = *rect; clr->fCanIgnoreRect = canIgnoreRect; return clr; }
void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, GrRenderTarget* renderTarget) { SkIRect r; if (NULL == renderTarget) { renderTarget = this->drawState()->getRenderTarget(); SkASSERT(renderTarget); } if (NULL == rect) { // We could do something smart and remove previous draws and clears to // the current render target. If we get that smart we have to make sure // those draws aren't read before this clear (render-to-texture). r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); rect = &r; } Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); GrColorIsPMAssert(color); clr->fColor = color; clr->fRect = *rect; clr->fCanIgnoreRect = canIgnoreRect; this->recordTraceMarkersIfNecessary(); }
void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) { GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget); // parent class should never let us get here with no RT SkASSERT(!clip.hasWindowRectangles()); CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; VkClearColorValue vkColor = {{color.fR, color.fG, color.fB, color.fA}}; if (cbInfo.fIsEmpty && !clip.scissorEnabled()) { // Change the render pass to do a clear load GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE); // Preserve the stencil buffer's load & store settings GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp); const GrVkRenderPass* oldRP = cbInfo.fRenderPass; const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle(); if (rpHandle.isValid()) { cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, vkColorOps, vkStencilOps); } else { cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT, vkColorOps, vkStencilOps); } SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP)); oldRP->unref(fGpu); cbInfo.fColorClearValue.color = {{color.fR, color.fG, color.fB, color.fA}}; cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear; // Update command buffer bounds cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); return; } // We always do a sub rect clear with clearAttachments since we are inside a render pass VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; if (!clip.scissorEnabled()) { vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) { vkRect = clip.scissorRect(); } else { const SkIRect& scissor = clip.scissorRect(); vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom, scissor.fRight, fRenderTarget->height() - scissor.fTop); } clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; clearRect.baseArrayLayer = 0; clearRect.layerCount = 1; uint32_t colorIndex; SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex)); VkClearAttachment attachment; attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; attachment.colorAttachment = colorIndex; attachment.clearValue.color = vkColor; cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect); cbInfo.fIsEmpty = false; // Update command buffer bounds if (!clip.scissorEnabled()) { cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); } else { cbInfo.fBounds.join(SkRect::Make(clip.scissorRect())); } return; }
void GrVkGpuCommandBuffer::onClear(GrRenderTarget* target, const GrFixedClip& clip, GrColor color) { // parent class should never let us get here with no RT SkASSERT(target); SkASSERT(!clip.hasWindowRectangles()); VkClearColorValue vkColor; GrColorToRGBAFloat(color, vkColor.float32); GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); if (fIsEmpty && !clip.scissorEnabled()) { // We will change the render pass to do a clear load instead GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE); GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE); const GrVkRenderPass* oldRP = fRenderPass; const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle(); if (rpHandle.isValid()) { fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, vkColorOps, vkStencilOps); } else { fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT, vkColorOps, vkStencilOps); } SkASSERT(fRenderPass->isCompatible(*oldRP)); oldRP->unref(fGpu); GrColorToRGBAFloat(color, fColorClearValue.color.float32); fStartsWithClear = true; return; } // We always do a sub rect clear with clearAttachments since we are inside a render pass VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; if (!clip.scissorEnabled()) { vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height()); } else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) { vkRect = clip.scissorRect(); } else { const SkIRect& scissor = clip.scissorRect(); vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom, scissor.fRight, vkRT->height() - scissor.fTop); } clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; clearRect.baseArrayLayer = 0; clearRect.layerCount = 1; uint32_t colorIndex; SkAssertResult(fRenderPass->colorAttachmentIndex(&colorIndex)); VkClearAttachment attachment; attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; attachment.colorAttachment = colorIndex; attachment.clearValue.color = vkColor; fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect); fIsEmpty = false; return; }