本文整理汇总了C++中SkSTArray类的典型用法代码示例。如果您正苦于以下问题:C++ SkSTArray类的具体用法?C++ SkSTArray怎么用?C++ SkSTArray使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SkSTArray类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GrAssert
GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
const GrEffectStage& stage,
GrGLEffect::EffectKey key,
const char* fsInColor,
const char* fsOutColor,
const char* vsInCoord,
SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
GrAssert(NULL != stage.getEffect());
const GrEffect& effect = *stage.getEffect();
int numTextures = effect.numTextures();
SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
textureSamplers.push_back_n(numTextures);
for (int i = 0; i < numTextures; ++i) {
textureSamplers[i].init(this, &effect.textureAccess(i), i);
samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
}
GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect);
// Enclose custom code in a block to avoid namespace conflicts
this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
this->fFSCode.appendf("\t{ // %s \n", glEffect->name());
glEffect->emitCode(this,
stage,
key,
vsInCoord,
fsOutColor,
fsInColor,
textureSamplers);
this->fVSCode.appendf("\t}\n");
this->fFSCode.appendf("\t}\n");
return glEffect;
}
示例2: INHERITED
GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu, kIsWrapped) {
#ifndef SK_SCALAR_IS_FLOAT
GrCrash("Assumes scalar is float.");
#endif
SkASSERT(!path.isEmpty());
GL_CALL_RET(fPathID, GenPaths(1));
SkSTArray<16, GrGLubyte, true> pathCommands;
SkSTArray<16, SkPoint, true> pathPoints;
int verbCnt = path.countVerbs();
int pointCnt = path.countPoints();
pathCommands.resize_back(verbCnt);
pathPoints.resize_back(pointCnt);
// TODO: Direct access to path points since we could pass them on directly.
path.getPoints(&pathPoints[0], pointCnt);
path.getVerbs(&pathCommands[0], verbCnt);
GR_DEBUGCODE(int numPts = 0);
for (int i = 0; i < verbCnt; ++i) {
SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
pathCommands[i] = verb_to_gl_path_cmd(v);
GR_DEBUGCODE(numPts += num_pts(v));
}
GrAssert(pathPoints.count() == numPts);
GL_CALL(PathCommands(fPathID,
verbCnt, &pathCommands[0],
2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]));
fBounds = path.getBounds();
}
开发者ID:IllusionRom-deprecated,项目名称:android_platform_external_chromium_org_third_party_skia_src,代码行数:33,代码来源:GrGLPath.cpp
示例3: onAsPaint
bool SkSVGLinearGradient::onAsPaint(const SkSVGRenderContext& ctx, SkPaint* paint) const {
const auto& lctx = ctx.lengthContext();
const auto x1 = lctx.resolve(fX1, SkSVGLengthContext::LengthType::kHorizontal);
const auto y1 = lctx.resolve(fY1, SkSVGLengthContext::LengthType::kVertical);
const auto x2 = lctx.resolve(fX2, SkSVGLengthContext::LengthType::kHorizontal);
const auto y2 = lctx.resolve(fY2, SkSVGLengthContext::LengthType::kVertical);
const SkPoint pts[2] = { {x1, y1}, {x2, y2}};
SkSTArray<2, SkColor , true> colors;
SkSTArray<2, SkScalar, true> pos;
this->collectColorStops(ctx, &pos, &colors);
// TODO:
// * stop (lazy?) sorting
// * href loop detection
// * href attribute inheritance (not just color stops)
// * objectBoundingBox units support
static_assert(static_cast<SkShader::TileMode>(SkSVGSpreadMethod::Type::kPad) ==
SkShader::kClamp_TileMode, "SkSVGSpreadMethod::Type is out of sync");
static_assert(static_cast<SkShader::TileMode>(SkSVGSpreadMethod::Type::kRepeat) ==
SkShader::kRepeat_TileMode, "SkSVGSpreadMethod::Type is out of sync");
static_assert(static_cast<SkShader::TileMode>(SkSVGSpreadMethod::Type::kReflect) ==
SkShader::kMirror_TileMode, "SkSVGSpreadMethod::Type is out of sync");
const auto tileMode = static_cast<SkShader::TileMode>(fSpreadMethod.type());
paint->setShader(SkGradientShader::MakeLinear(pts, colors.begin(), pos.begin(), colors.count(),
tileMode, 0, &fGradientTransform.value()));
return true;
}
示例4: test_unnecessary_alloc
void test_unnecessary_alloc(skiatest::Reporter* reporter) {
{
SkTArray<int> a;
REPORTER_ASSERT(reporter, a.allocCntForTest() == 0);
}
{
SkSTArray<10, int> a;
REPORTER_ASSERT(reporter, a.allocCntForTest() == 10);
}
{
SkTArray<int> a(1);
REPORTER_ASSERT(reporter, a.allocCntForTest() >= 1);
}
{
SkTArray<int> a, b;
b = a;
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
{
SkSTArray<10, int> a;
SkTArray<int> b;
b = a;
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
{
SkTArray<int> a;
SkTArray<int> b(a);
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
{
SkSTArray<10, int> a;
SkTArray<int> b(a);
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
{
SkTArray<int> a;
SkTArray<int> b(std::move(a));
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
{
SkSTArray<10, int> a;
SkTArray<int> b(std::move(a));
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
{
SkTArray<int> a;
SkTArray<int> b;
b = std::move(a);
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
{
SkSTArray<10, int> a;
SkTArray<int> b;
b = std::move(a);
REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
}
}
示例5: add_cubic_segments
static inline void add_cubic_segments(const SkPoint pts[4],
SkPath::Direction dir,
SegmentArray* segments) {
SkSTArray<15, SkPoint, true> quads;
GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads);
int count = quads.count();
for (int q = 0; q < count; q += 3) {
add_quad_segment(&quads[q], segments);
}
}
示例6: onExecute
void onExecute(GrOpFlushState* state) override {
GrRenderTarget* rt = state->drawOpArgs().fRenderTarget;
GrPipeline pipeline(rt, fScissorState, SkBlendMode::kSrc);
SkSTArray<kNumMeshes, GrMesh> meshes;
for (int i = 0; i < kNumMeshes; ++i) {
GrMesh& mesh = meshes.emplace_back(GrPrimitiveType::kTriangleStrip);
mesh.setNonIndexedNonInstanced(4);
mesh.setVertexData(fVertexBuffer.get(), 4 * i);
}
state->commandBuffer()->draw(pipeline, GrPipelineDynamicStateTestProcessor(),
meshes.begin(), kDynamicStates, 4,
SkRect::MakeIWH(kScreenSize, kScreenSize));
}
示例7: onRevalidate
SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) {
// TODO: we could potentially track invals which don't require rebuilding the blob.
SkPaint font;
font.setFlags(fFlags);
font.setTypeface(fTypeface);
font.setTextSize(fSize);
font.setTextScaleX(fScaleX);
font.setTextSkewX(fSkewX);
font.setTextAlign(fAlign);
font.setHinting(fHinting);
// First, convert to glyphIDs.
font.setTextEncoding(SkPaint::kUTF8_TextEncoding);
SkSTArray<256, SkGlyphID, true> glyphs;
glyphs.reset(font.textToGlyphs(fText.c_str(), fText.size(), nullptr));
SkAssertResult(font.textToGlyphs(fText.c_str(), fText.size(), glyphs.begin()) == glyphs.count());
font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
// Next, build the cached blob.
SkTextBlobBuilder builder;
const auto& buf = builder.allocRun(font, glyphs.count(), 0, 0, nullptr);
if (!buf.glyphs) {
fBlob.reset();
return SkRect::MakeEmpty();
}
memcpy(buf.glyphs, glyphs.begin(), glyphs.count() * sizeof(SkGlyphID));
fBlob = builder.make();
return fBlob
? fBlob->bounds().makeOffset(fPosition.x(), fPosition.y())
: SkRect::MakeEmpty();
}
示例8: TextBlob
const GrStencilAndCoverTextContext::TextBlob&
GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob,
const SkPaint& skPaint) {
// The font-related parameters are baked into the text blob and will override this skPaint, so
// the only remaining properties that can affect a TextBlob are the ones related to stroke.
if (SkPaint::kFill_Style == skPaint.getStyle()) { // Fast path.
if (TextBlob** found = fBlobIdCache.find(skBlob->uniqueID())) {
fLRUList.remove(*found);
fLRUList.addToTail(*found);
return **found;
}
TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint, fContext,
&fSurfaceProps);
this->purgeToFit(*blob);
fBlobIdCache.set(skBlob->uniqueID(), blob);
fLRUList.addToTail(blob);
fCacheSize += blob->cpuMemorySize();
return *blob;
} else {
GrStrokeInfo stroke(skPaint);
SkSTArray<4, uint32_t, true> key;
key.reset(1 + stroke.computeUniqueKeyFragmentData32Cnt());
key[0] = skBlob->uniqueID();
stroke.asUniqueKeyFragment(&key[1]);
if (TextBlob** found = fBlobKeyCache.find(key)) {
fLRUList.remove(*found);
fLRUList.addToTail(*found);
return **found;
}
TextBlob* blob = new TextBlob(key, skBlob, skPaint, fContext, &fSurfaceProps);
this->purgeToFit(*blob);
fBlobKeyCache.set(blob);
fLRUList.addToTail(blob);
fCacheSize += blob->cpuMemorySize();
return *blob;
}
}
示例9: get_geometry
static bool get_geometry(const SkPath& path, const SkMatrix& m, PLSVertices& triVertices,
PLSVertices& quadVertices, GrResourceProvider* resourceProvider,
SkRect bounds) {
SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, m, bounds);
int contourCnt;
int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, tol);
if (maxPts <= 0) {
return 0;
}
SkPath linesOnlyPath;
linesOnlyPath.setFillType(path.getFillType());
SkSTArray<15, SkPoint, true> quadPoints;
SkPath::Iter iter(path, true);
bool done = false;
while (!done) {
SkPoint pts[4];
SkPath::Verb verb = iter.next(pts);
switch (verb) {
case SkPath::kMove_Verb:
SkASSERT(quadPoints.count() % 3 == 0);
for (int i = 0; i < quadPoints.count(); i += 3) {
add_quad(&quadPoints[i], quadVertices);
}
quadPoints.reset();
m.mapPoints(&pts[0], 1);
linesOnlyPath.moveTo(pts[0]);
break;
case SkPath::kLine_Verb:
m.mapPoints(&pts[1], 1);
linesOnlyPath.lineTo(pts[1]);
break;
case SkPath::kQuad_Verb:
m.mapPoints(pts, 3);
linesOnlyPath.lineTo(pts[2]);
quadPoints.push_back(pts[0]);
quadPoints.push_back(pts[1]);
quadPoints.push_back(pts[2]);
break;
case SkPath::kCubic_Verb: {
m.mapPoints(pts, 4);
SkSTArray<15, SkPoint, true> quads;
GrPathUtils::convertCubicToQuads(pts, kCubicTolerance, &quads);
int count = quads.count();
for (int q = 0; q < count; q += 3) {
linesOnlyPath.lineTo(quads[q + 2]);
quadPoints.push_back(quads[q]);
quadPoints.push_back(quads[q + 1]);
quadPoints.push_back(quads[q + 2]);
}
break;
}
case SkPath::kConic_Verb: {
m.mapPoints(pts, 3);
SkScalar weight = iter.conicWeight();
SkAutoConicToQuads converter;
const SkPoint* quads = converter.computeQuads(pts, weight, kConicTolerance);
int count = converter.countQuads();
for (int i = 0; i < count; ++i) {
linesOnlyPath.lineTo(quads[2 * i + 2]);
quadPoints.push_back(quads[2 * i]);
quadPoints.push_back(quads[2 * i + 1]);
quadPoints.push_back(quads[2 * i + 2]);
}
break;
}
case SkPath::kClose_Verb:
linesOnlyPath.close();
break;
case SkPath::kDone_Verb:
done = true;
break;
default: SkASSERT(false);
}
}
SkASSERT(quadPoints.count() % 3 == 0);
for (int i = 0; i < quadPoints.count(); i += 3) {
add_quad(&quadPoints[i], quadVertices);
}
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey key;
GrUniqueKey::Builder builder(&key, kDomain, 2);
builder[0] = path.getGenerationID();
builder[1] = path.getFillType();
builder.finish();
GrTessellator::WindingVertex* windingVertices;
int triVertexCount = GrTessellator::PathToVertices(linesOnlyPath, 0, bounds, &windingVertices);
if (triVertexCount > 0) {
for (int i = 0; i < triVertexCount; i += 3) {
SkPoint p1 = windingVertices[i].fPos;
SkPoint p2 = windingVertices[i + 1].fPos;
SkPoint p3 = windingVertices[i + 2].fPos;
int winding = windingVertices[i].fWinding;
SkASSERT(windingVertices[i + 1].fWinding == winding);
SkASSERT(windingVertices[i + 2].fWinding == winding);
SkScalar cross = (p2 - p1).cross(p3 - p1);
SkPoint bloated[3] = { p1, p2, p3 };
if (cross < 0.0f) {
SkTSwap(p1, p3);
//.........这里部分代码省略.........
示例10: Create
GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
int shaderStageCount,
GrPrimitiveType primitiveType,
const GrVkRenderPass& renderPass,
VkPipelineLayout layout,
VkPipelineCache cache) {
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
VkVertexInputBindingDescription bindingDesc;
SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc;
SkASSERT(primProc.numAttribs() <= gpu->vkCaps().maxVertexAttributes());
VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(primProc.numAttribs());
setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDesc, 1, pAttribs);
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
setup_input_assembly_state(primitiveType, &inputAssemblyInfo);
VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
setup_depth_stencil_state(gpu, pipeline.getStencil(), &depthStencilInfo);
GrRenderTarget* rt = pipeline.getRenderTarget();
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
VkPipelineViewportStateCreateInfo viewportInfo;
setup_viewport_scissor_state(gpu, pipeline, vkRT, &viewportInfo);
VkPipelineMultisampleStateCreateInfo multisampleInfo;
setup_multisample_state(pipeline, primProc, gpu->caps(), &multisampleInfo);
// We will only have one color attachment per pipeline.
VkPipelineColorBlendAttachmentState attachmentStates[1];
VkPipelineColorBlendStateCreateInfo colorBlendInfo;
setup_color_blend_state(gpu, pipeline, &colorBlendInfo, attachmentStates);
VkPipelineRasterizationStateCreateInfo rasterInfo;
setup_raster_state(gpu, pipeline, &rasterInfo);
VkDynamicState dynamicStates[3];
VkPipelineDynamicStateCreateInfo dynamicInfo;
setup_dynamic_state(gpu, pipeline, &dynamicInfo, dynamicStates);
VkGraphicsPipelineCreateInfo pipelineCreateInfo;
memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineCreateInfo.pNext = nullptr;
pipelineCreateInfo.flags = 0;
pipelineCreateInfo.stageCount = shaderStageCount;
pipelineCreateInfo.pStages = shaderStageInfo;
pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
pipelineCreateInfo.pTessellationState = nullptr;
pipelineCreateInfo.pViewportState = &viewportInfo;
pipelineCreateInfo.pRasterizationState = &rasterInfo;
pipelineCreateInfo.pMultisampleState = &multisampleInfo;
pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
pipelineCreateInfo.pDynamicState = &dynamicInfo;
pipelineCreateInfo.layout = layout;
pipelineCreateInfo.renderPass = renderPass.vkRenderPass();
pipelineCreateInfo.subpass = 0;
pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
pipelineCreateInfo.basePipelineIndex = -1;
VkPipeline vkPipeline;
VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->device(),
cache, 1,
&pipelineCreateInfo,
nullptr, &vkPipeline));
if (err) {
return nullptr;
}
return new GrVkPipeline(vkPipeline);
}
示例11: onPrepareDraws
void onPrepareDraws(Target* target) const override {
#ifndef SK_IGNORE_LINEONLY_AA_CONVEX_PATH_OPTS
if (this->linesOnly()) {
this->prepareLinesOnlyDraws(target);
return;
}
#endif
int instanceCount = fGeoData.count();
SkMatrix invert;
if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) {
SkDebugf("Could not invert viewmatrix\n");
return;
}
// Setup GrGeometryProcessor
sk_sp<GrGeometryProcessor> quadProcessor(
QuadEdgeEffect::Make(this->color(), invert, this->usesLocalCoords()));
// TODO generate all segments for all paths and use one vertex buffer
for (int i = 0; i < instanceCount; i++) {
const Geometry& args = fGeoData[i];
// We use the fact that SkPath::transform path does subdivision based on
// perspective. Otherwise, we apply the view matrix when copying to the
// segment representation.
const SkMatrix* viewMatrix = &args.fViewMatrix;
// We avoid initializing the path unless we have to
const SkPath* pathPtr = &args.fPath;
SkTLazy<SkPath> tmpPath;
if (viewMatrix->hasPerspective()) {
SkPath* tmpPathPtr = tmpPath.init(*pathPtr);
tmpPathPtr->setIsVolatile(true);
tmpPathPtr->transform(*viewMatrix);
viewMatrix = &SkMatrix::I();
pathPtr = tmpPathPtr;
}
int vertexCount;
int indexCount;
enum {
kPreallocSegmentCnt = 512 / sizeof(Segment),
kPreallocDrawCnt = 4,
};
SkSTArray<kPreallocSegmentCnt, Segment, true> segments;
SkPoint fanPt;
if (!get_segments(*pathPtr, *viewMatrix, &segments, &fanPt, &vertexCount,
&indexCount)) {
continue;
}
const GrBuffer* vertexBuffer;
int firstVertex;
size_t vertexStride = quadProcessor->getVertexStride();
QuadVertex* verts = reinterpret_cast<QuadVertex*>(target->makeVertexSpace(
vertexStride, vertexCount, &vertexBuffer, &firstVertex));
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
}
const GrBuffer* indexBuffer;
int firstIndex;
uint16_t *idxs = target->makeIndexSpace(indexCount, &indexBuffer, &firstIndex);
if (!idxs) {
SkDebugf("Could not allocate indices\n");
return;
}
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
create_vertices(segments, fanPt, &draws, verts, idxs);
GrMesh mesh;
for (int j = 0; j < draws.count(); ++j) {
const Draw& draw = draws[j];
mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer,
firstVertex, firstIndex, draw.fVertexCnt, draw.fIndexCnt);
target->draw(quadProcessor.get(), mesh);
firstVertex += draw.fVertexCnt;
firstIndex += draw.fIndexCnt;
}
}
}
示例12: GR_CREATE_TRACE_MARKER_CONTEXT
// MDB TODO: make use of the 'proxy' parameter.
GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
GrResourceCache::FlushType type,
int numSemaphores,
GrBackendSemaphore backendSemaphores[]) {
GR_CREATE_TRACE_MARKER_CONTEXT("GrDrawingManager", "internalFlush", fContext);
if (fFlushing || this->wasAbandoned()) {
return GrSemaphoresSubmitted::kNo;
}
GrGpu* gpu = fContext->contextPriv().getGpu();
if (!gpu) {
return GrSemaphoresSubmitted::kNo; // Can't flush while DDL recording
}
fFlushing = true;
for (int i = 0; i < fOpLists.count(); ++i) {
// Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
// needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
// but need to be flushed anyway. Closing such GrOpLists here will mean new
// GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
fOpLists[i]->makeClosed(*fContext->caps());
}
#ifdef SK_DEBUG
// This block checks for any unnecessary splits in the opLists. If two sequential opLists
// share the same backing GrSurfaceProxy it means the opList was artificially split.
if (fOpLists.count()) {
GrRenderTargetOpList* prevOpList = fOpLists[0]->asRenderTargetOpList();
for (int i = 1; i < fOpLists.count(); ++i) {
GrRenderTargetOpList* curOpList = fOpLists[i]->asRenderTargetOpList();
if (prevOpList && curOpList) {
SkASSERT(prevOpList->fTarget.get() != curOpList->fTarget.get());
}
prevOpList = curOpList;
}
}
#endif
if (fSortRenderTargets) {
SkDEBUGCODE(bool result =) SkTTopoSort<GrOpList, GrOpList::TopoSortTraits>(&fOpLists);
SkASSERT(result);
}
GrOpFlushState flushState(gpu, fContext->contextPriv().resourceProvider(),
&fTokenTracker);
GrOnFlushResourceProvider onFlushProvider(this);
// TODO: AFAICT the only reason fFlushState is on GrDrawingManager rather than on the
// stack here is to preserve the flush tokens.
// Prepare any onFlush op lists (e.g. atlases).
if (!fOnFlushCBObjects.empty()) {
fFlushingOpListIDs.reset(fOpLists.count());
for (int i = 0; i < fOpLists.count(); ++i) {
fFlushingOpListIDs[i] = fOpLists[i]->uniqueID();
}
SkSTArray<4, sk_sp<GrRenderTargetContext>> renderTargetContexts;
for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
onFlushCBObject->preFlush(&onFlushProvider,
fFlushingOpListIDs.begin(), fFlushingOpListIDs.count(),
&renderTargetContexts);
for (const sk_sp<GrRenderTargetContext>& rtc : renderTargetContexts) {
sk_sp<GrRenderTargetOpList> onFlushOpList = sk_ref_sp(rtc->getRTOpList());
if (!onFlushOpList) {
continue; // Odd - but not a big deal
}
#ifdef SK_DEBUG
// OnFlush callbacks are already invoked during flush, and are therefore expected to
// handle resource allocation & usage on their own. (No deferred or lazy proxies!)
onFlushOpList->visitProxies_debugOnly([](GrSurfaceProxy* p) {
SkASSERT(!p->asTextureProxy() || !p->asTextureProxy()->texPriv().isDeferred());
SkASSERT(GrSurfaceProxy::LazyState::kNot == p->lazyInstantiationState());
});
#endif
onFlushOpList->makeClosed(*fContext->caps());
onFlushOpList->prepare(&flushState);
fOnFlushCBOpLists.push_back(std::move(onFlushOpList));
}
renderTargetContexts.reset();
}
}
#if 0
// Enable this to print out verbose GrOp information
for (int i = 0; i < fOpLists.count(); ++i) {
SkDEBUGCODE(fOpLists[i]->dump();)
}
#endif
int startIndex, stopIndex;
bool flushed = false;
{
GrResourceAllocator alloc(fContext->contextPriv().resourceProvider());
for (int i = 0; i < fOpLists.count(); ++i) {
fOpLists[i]->gatherProxyIntervals(&alloc);
alloc.markEndOfOpList(i);
//.........这里部分代码省略.........
示例13: is_linear_inner
static bool is_linear_inner(const SkDQuad& q1, double t1s, double t1e, const SkDQuad& q2,
double t2s, double t2e, SkIntersections* i, bool* subDivide) {
SkDQuad hull = q1.subDivide(t1s, t1e);
SkDLine line = {{hull[2], hull[0]}};
const SkDLine* testLines[] = { &line, (const SkDLine*) &hull[0], (const SkDLine*) &hull[1] };
const size_t kTestCount = SK_ARRAY_COUNT(testLines);
SkSTArray<kTestCount * 2, double, true> tsFound;
for (size_t index = 0; index < kTestCount; ++index) {
SkIntersections rootTs;
rootTs.allowNear(false);
int roots = rootTs.intersect(q2, *testLines[index]);
for (int idx2 = 0; idx2 < roots; ++idx2) {
double t = rootTs[0][idx2];
#ifdef SK_DEBUG
SkDPoint qPt = q2.ptAtT(t);
SkDPoint lPt = testLines[index]->ptAtT(rootTs[1][idx2]);
SkASSERT(qPt.approximatelyEqual(lPt));
#endif
if (approximately_negative(t - t2s) || approximately_positive(t - t2e)) {
continue;
}
tsFound.push_back(rootTs[0][idx2]);
}
}
int tCount = tsFound.count();
if (tCount <= 0) {
return true;
}
double tMin, tMax;
if (tCount == 1) {
tMin = tMax = tsFound[0];
} else {
SkASSERT(tCount > 1);
SkTQSort<double>(tsFound.begin(), tsFound.end() - 1);
tMin = tsFound[0];
tMax = tsFound[tsFound.count() - 1];
}
SkDPoint end = q2.ptAtT(t2s);
bool startInTriangle = hull.pointInHull(end);
if (startInTriangle) {
tMin = t2s;
}
end = q2.ptAtT(t2e);
bool endInTriangle = hull.pointInHull(end);
if (endInTriangle) {
tMax = t2e;
}
int split = 0;
SkDVector dxy1, dxy2;
if (tMin != tMax || tCount > 2) {
dxy2 = q2.dxdyAtT(tMin);
for (int index = 1; index < tCount; ++index) {
dxy1 = dxy2;
dxy2 = q2.dxdyAtT(tsFound[index]);
double dot = dxy1.dot(dxy2);
if (dot < 0) {
split = index - 1;
break;
}
}
}
if (split == 0) { // there's one point
if (add_intercept(q1, q2, tMin, tMax, i, subDivide)) {
return true;
}
i->swap();
return is_linear_inner(q2, tMin, tMax, q1, t1s, t1e, i, subDivide);
}
// At this point, we have two ranges of t values -- treat each separately at the split
bool result;
if (add_intercept(q1, q2, tMin, tsFound[split - 1], i, subDivide)) {
result = true;
} else {
i->swap();
result = is_linear_inner(q2, tMin, tsFound[split - 1], q1, t1s, t1e, i, subDivide);
}
if (add_intercept(q1, q2, tsFound[split], tMax, i, subDivide)) {
result = true;
} else {
i->swap();
result |= is_linear_inner(q2, tsFound[split], tMax, q1, t1s, t1e, i, subDivide);
}
return result;
}
开发者ID:IllusionRom-deprecated,项目名称:android_platform_external_chromium_org_third_party_skia_src,代码行数:84,代码来源:SkDQuadIntersection.cpp
示例14: get_analytic_clip_processor
static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elements,
bool abortIfAA,
SkVector& clipToRTOffset,
const SkRect* drawBounds,
sk_sp<GrFragmentProcessor>* resultFP) {
SkRect boundsInClipSpace;
if (drawBounds) {
boundsInClipSpace = *drawBounds;
boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
}
SkASSERT(elements.count() <= kMaxAnalyticElements);
SkSTArray<kMaxAnalyticElements, sk_sp<GrFragmentProcessor>> fps;
GrReducedClip::ElementList::Iter iter(elements);
while (iter.get()) {
SkRegion::Op op = iter.get()->getOp();
bool invert;
bool skip = false;
switch (op) {
case SkRegion::kReplace_Op:
SkASSERT(iter.get() == elements.head());
// Fallthrough, handled same as intersect.
case SkRegion::kIntersect_Op:
invert = false;
if (drawBounds && iter.get()->contains(boundsInClipSpace)) {
skip = true;
}
break;
case SkRegion::kDifference_Op:
invert = true;
// We don't currently have a cheap test for whether a rect is fully outside an
// element's primitive, so don't attempt to set skip.
break;
default:
return false;
}
if (!skip) {
GrPrimitiveEdgeType edgeType;
if (iter.get()->isAA()) {
if (abortIfAA) {
return false;
}
edgeType =
invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_GrProcessorEdgeType;
} else {
edgeType =
invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType;
}
switch (iter.get()->getType()) {
case SkClipStack::Element::kPath_Type:
fps.emplace_back(GrConvexPolyEffect::Make(edgeType, iter.get()->getPath(),
&clipToRTOffset));
break;
case SkClipStack::Element::kRRect_Type: {
SkRRect rrect = iter.get()->getRRect();
rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
fps.emplace_back(GrRRectEffect::Make(edgeType, rrect));
break;
}
case SkClipStack::Element::kRect_Type: {
SkRect rect = iter.get()->getRect();
rect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
fps.emplace_back(GrConvexPolyEffect::Make(edgeType, rect));
break;
}
default:
break;
}
if (!fps.back()) {
return false;
}
}
iter.next();
}
*resultFP = nullptr;
if (fps.count()) {
*resultFP = GrFragmentProcessor::RunInSeries(fps.begin(), fps.count());
}
return true;
}
示例15: generateGeometry
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
int instanceCount = fGeoData.count();
SkMatrix invert;
if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) {
SkDebugf("Could not invert viewmatrix\n");
return;
}
// Setup GrGeometryProcessor
SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(this->color(),
invert));
batchTarget->initDraw(quadProcessor, pipeline);
// TODO remove this when batch is everywhere
GrPipelineInfo init;
init.fColorIgnored = fBatch.fColorIgnored;
init.fOverrideColor = GrColor_ILLEGAL;
init.fCoverageIgnored = fBatch.fCoverageIgnored;
init.fUsesLocalCoords = this->usesLocalCoords();
quadProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init);
// TODO generate all segments for all paths and use one vertex buffer
for (int i = 0; i < instanceCount; i++) {
Geometry& args = fGeoData[i];
// We use the fact that SkPath::transform path does subdivision based on
// perspective. Otherwise, we apply the view matrix when copying to the
// segment representation.
const SkMatrix* viewMatrix = &args.fViewMatrix;
if (viewMatrix->hasPerspective()) {
args.fPath.transform(*viewMatrix);
viewMatrix = &SkMatrix::I();
}
int vertexCount;
int indexCount;
enum {
kPreallocSegmentCnt = 512 / sizeof(Segment),
kPreallocDrawCnt = 4,
};
SkSTArray<kPreallocSegmentCnt, Segment, true> segments;
SkPoint fanPt;
if (!get_segments(args.fPath, *viewMatrix, &segments, &fanPt, &vertexCount,
&indexCount)) {
continue;
}
const GrVertexBuffer* vertexBuffer;
int firstVertex;
size_t vertexStride = quadProcessor->getVertexStride();
void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
vertexCount,
&vertexBuffer,
&firstVertex);
if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
const GrIndexBuffer* indexBuffer;
int firstIndex;
void *indices = batchTarget->indexPool()->makeSpace(indexCount,
&indexBuffer,
&firstIndex);
if (!indices) {
SkDebugf("Could not allocate indices\n");
return;
}
QuadVertex* verts = reinterpret_cast<QuadVertex*>(vertices);
uint16_t* idxs = reinterpret_cast<uint16_t*>(indices);
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
create_vertices(segments, fanPt, &draws, verts, idxs);
GrDrawTarget::DrawInfo info;
info.setVertexBuffer(vertexBuffer);
info.setIndexBuffer(indexBuffer);
info.setPrimitiveType(kTriangles_GrPrimitiveType);
info.setStartIndex(firstIndex);
int vOffset = 0;
for (int i = 0; i < draws.count(); ++i) {
const Draw& draw = draws[i];
info.setStartVertex(vOffset + firstVertex);
info.setVertexCount(draw.fVertexCnt);
info.setIndexCount(draw.fIndexCnt);
batchTarget->draw(info);
vOffset += draw.fVertexCnt;
}
}
}