Flutter Engine
The Flutter Engine
Classes | Namespaces | Functions
GrGpuBufferTest.cpp File Reference
#include "include/core/SkBlendMode.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkAlign.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrDrawingManager.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrGpuBuffer.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrPipeline.h"
#include "src/gpu/ganesh/GrPixmap.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include <algorithm>
#include <cstring>
#include <initializer_list>
#include <memory>
#include <string_view>
#include <utility>

Go to the source code of this file.

Classes

class  TestVertexOp
 

Namespaces

namespace  skgpu
 

Functions

 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (GrGpuBufferTransferTest, reporter, ctxInfo, CtsEnforcement::kApiLevel_U)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (GrGpuBufferUpdateDataTest, reporter, ctxInfo, CtsEnforcement::kApiLevel_U)
 

Function Documentation

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [1/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( GrGpuBufferTransferTest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_U   
)

Definition at line 219 of file GrGpuBufferTest.cpp.

222 {
223 if (!ctxInfo.directContext()->priv().caps()->transferFromBufferToBufferSupport()) {
224 return;
225 }
226
227 GrDirectContext* dc = ctxInfo.directContext();
228
230
231 GrResourceProvider* rp = ctxInfo.directContext()->priv().resourceProvider();
232
233 GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();
234
235 auto create_cpu_to_gpu_buffer = [&](int baseVertex) {
236 // Ensure any extra vertices are offscreen
237 int totalVertices = baseVertex + 6;
238 auto points = std::make_unique<SkPoint[]>(totalVertices);
239 SkPoint offscreenPt{-10000, -10000};
240 std::fill_n(points.get(), totalVertices, offscreenPt);
241
242 // set the quad at the desired base vertex
243 static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
244 {1, 0}, {0, 1}, {1, 1}};
245 std::copy_n(kUnitQuad, 6, points.get() + baseVertex);
246
247 return rp->createBuffer(points.get(),
248 totalVertices*sizeof(SkPoint),
251 };
252
253 auto create_vertex_buffer = [&](sk_sp<GrGpuBuffer> srcBuffer,
254 int srcBaseVertex,
255 int vbBaseVertex,
256 bool useTask,
257 bool minSizedTransfers) {
258 // make initialization data of offscreen points.
259 int dstVertexCount = vbBaseVertex + 6;
260 auto points = std::make_unique<SkPoint[]>(dstVertexCount);
261 SkPoint offscreenPt{-10000, -10000};
262 std::fill_n(points.get(), dstVertexCount, offscreenPt);
263
265 dstVertexCount*sizeof(SkPoint),
268
269 // copy actual quad data from the source buffer to our new vb.
270
271 static constexpr size_t kTotalSize = 6*sizeof(SkPoint);
272
273 size_t srcOffset = srcBaseVertex*sizeof(SkPoint);
274 size_t vbOffset = vbBaseVertex*sizeof(SkPoint);
275
276 size_t alignment = gpu->caps()->transferFromBufferToBufferAlignment();
277 SkASSERT(kTotalSize % alignment == 0);
278 SkASSERT(sizeof(SkPoint) % alignment == 0);
279
280 if (minSizedTransfers) {
281 for (size_t n = kTotalSize/alignment, i = 0; i < n; ++i) {
282 if (useTask) {
283 dm->newBufferTransferTask(srcBuffer,
284 srcOffset + i*alignment,
285 vb,
286 vbOffset + i*alignment,
287 alignment);
288 } else {
289 gpu->transferFromBufferToBuffer(srcBuffer,
290 srcOffset + i*alignment,
291 vb,
292 vbOffset + i*alignment,
293 alignment);
294 }
295 }
296 } else if (useTask) {
297 dm->newBufferTransferTask(srcBuffer, srcOffset, vb, vbOffset, kTotalSize);
298 } else {
299 gpu->transferFromBufferToBuffer(srcBuffer, srcOffset, vb, vbOffset, kTotalSize);
300 }
301 return vb;
302 };
303
306 nullptr,
308 {1, 1},
310 std::string_view{});
311 if (!sdc) {
312 ERRORF(reporter, "Could not create draw context");
313 return;
314 }
315
316 auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));
317
318 for (bool useTask : {false, true}) {
319 for (bool minSizedTransfers : {false, true}) {
320 for (int srcBaseVertex : {0, 5}) {
321 auto src = create_cpu_to_gpu_buffer(srcBaseVertex);
322 if (!src) {
323 ERRORF(reporter, "Could not create src buffer");
324 return;
325 }
326 for (int vbBaseVertex : {0, 2}) {
327 auto vb = create_vertex_buffer(src,
328 srcBaseVertex,
329 vbBaseVertex,
330 useTask,
331 minSizedTransfers);
332 if (!vb) {
333 ERRORF(reporter, "Could not create vertex buffer");
334 return;
335 }
336
337 static constexpr SkColor4f kRed{1, 0, 0, 1};
338
339 static constexpr SkRect kBounds{0, 0, 1, 1};
340
341 sdc->clear(kRed);
342
343 sdc->addDrawOp(nullptr, TestVertexOp::Make(dc,
344 vb,
345 vbBaseVertex,
346 /*vertexCount=*/6,
347 kBounds));
348
349 auto color = static_cast<SkPMColor4f*>(pm.addr());
350 *color = kRed.premul();
351 if (!sdc->readPixels(dc, pm, {0, 0})) {
352 ERRORF(reporter, "Read back failed.");
353 return;
354 }
355
356 static constexpr SkPMColor4f kGreen{0, 1, 0, 1};
357
358 REPORTER_ASSERT(reporter, *color == kGreen, "src base vertex: %d, "
359 "vb base vertex: %d, "
360 "use task: %d, "
361 "minSizedTransfers: %d",
362 srcBaseVertex,
363 vbBaseVertex,
364 useTask,
365 minSizedTransfers);
366 }
367 }
368 }
369 }
370}
reporter
Definition: FontMgrTest.cpp:39
@ kDynamic_GrAccessPattern
Definition: GrTypesPriv.h:426
static const int points[]
static const uint64_t kGreen
static const uint64_t kRed
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define ERRORF(r,...)
Definition: Test.h:293
size_t transferFromBufferToBufferAlignment() const
Definition: GrCaps.h:244
GrDirectContextPriv priv()
void newBufferTransferTask(sk_sp< GrGpuBuffer > src, size_t srcOffset, sk_sp< GrGpuBuffer > dst, size_t dstOffset, size_t size)
Definition: GrGpu.h:62
const GrCaps * caps() const
Definition: GrGpu.h:73
bool transferFromBufferToBuffer(sk_sp< GrGpuBuffer > src, size_t srcOffset, sk_sp< GrGpuBuffer > dst, size_t dstOffset, size_t size)
Definition: GrGpu.cpp:511
static GrPixmap Allocate(const GrImageInfo &info)
Definition: GrPixmap.h:101
GrDrawingManager * drawingManager()
sk_sp< GrGpuBuffer > createBuffer(size_t size, GrGpuBufferType, GrAccessPattern, ZeroInit)
GrResourceProviderPriv priv()
static GrOp::Owner Make(GrRecordingContext *context, sk_sp< GrGpuBuffer > buffer, int baseVertex, int vertexCount, const SkRect &bounds)
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)
DlColor color

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [2/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( GrGpuBufferUpdateDataTest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_U   
)

Definition at line 372 of file GrGpuBufferTest.cpp.

375 {
376 GrDirectContext* dc = ctxInfo.directContext();
377
378 GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();
379
380 static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
381 {1, 0}, {0, 1}, {1, 1}};
382
385 nullptr,
387 {1, 1},
389 std::string_view{});
390 if (!sdc) {
391 ERRORF(reporter, "Could not create draw context");
392 return;
393 }
394
395 auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));
396
397 for (bool piecewise : {false, true}) {
398 size_t alignment = piecewise ? gpu->caps()->bufferUpdateDataPreserveAlignment() : 1;
399 for (size_t offset : {size_t{0}, 4*sizeof(SkPoint), size_t{1}, size_t{27}}) {
400 // For non-discarding updates we may not be able to actually put the data at an
401 // arbitrary offset.
402 if (alignment > 1) {
403 offset = SkAlignTo(offset, alignment);
404 }
405 for (auto accessPattern : {kStatic_GrAccessPattern,
406 // kStream_GrAccessPattern, GrVkGpu asserts on this for VBs.
408 // Go direct to GrGpu to avoid caching/size adjustments at GrResourceProvider level.
409 // We add an extra size(SkPoint) to ensure that everything fits when we align the
410 // first point's location in the vb below.
411 auto vb = gpu->createBuffer(sizeof(kUnitQuad) + offset + sizeof(SkPoint),
413 accessPattern);
414 if (!vb) {
415 ERRORF(reporter, "Could not create vertex buffer");
416 return;
417 }
418
419 const void* src = kUnitQuad;
420 size_t updateSize = sizeof(kUnitQuad);
421 // The vertices in the VB must be aligned to the size of a vertex (because our draw
422 // call takes a base vertex index rather than a byte offset). So if we want our
423 // upload to begin at a non-aligned byte we shift the data in the src buffer so that
424 // it falls at a vertex alignment in the vb.
425 std::unique_ptr<char[]> tempSrc;
426 size_t baseVertex = offset/sizeof(SkPoint);
427 if (size_t r = offset%sizeof(SkPoint); r != 0) {
428 size_t pad = sizeof(SkPoint) - r;
429 updateSize += pad;
430 if (alignment > 1) {
431 updateSize = SkAlignTo(updateSize, alignment);
432 }
433 ++baseVertex;
434 tempSrc.reset(new char[updateSize]);
435 std::memcpy(tempSrc.get() + pad, kUnitQuad, sizeof(kUnitQuad));
436 src = tempSrc.get();
437 }
438 if (piecewise) {
439 // This is the minimum size we can transfer at once.
440 size_t pieceSize = alignment;
441
442 // Upload each piece from a buffer where the byte before and after the uploaded
443 // bytes are not the same values as want adjacent to the piece in the buffer.
444 // Thus, if updateData() transfers extra bytes around the source we should get a
445 // bad buffer.
446 auto piece = std::make_unique<unsigned char[]>(pieceSize + 2);
447 piece[0] = piece[pieceSize + 1] = 0xFF;
448
449 for (size_t o = 0; o < updateSize; o += pieceSize) {
450 memcpy(&piece[1], SkTAddOffset<const void>(src, o), pieceSize);
451 if (!vb->updateData(&piece[1], offset + o, pieceSize, /*preserve=*/true)) {
452 ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
453 return;
454 }
455 }
456 } else if (!vb->updateData(src, offset, updateSize, /*preserve=*/false)) {
457 ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
458 return;
459 }
460
461 static constexpr SkColor4f kRed{1, 0, 0, 1};
462
463 static constexpr SkRect kBounds{0, 0, 1, 1};
464
465 sdc->clear(kRed);
466
467 sdc->addDrawOp(nullptr, TestVertexOp::Make(dc,
468 vb,
469 baseVertex,
470 std::size(kUnitQuad),
471 kBounds));
472
473 auto color = static_cast<SkPMColor4f*>(pm.addr());
474 *color = kRed.premul();
475 if (!sdc->readPixels(dc, pm, {0, 0})) {
476 ERRORF(reporter, "Read back failed.");
477 return;
478 }
479
480 static constexpr SkPMColor4f kGreen{0, 1, 0, 1};
481
482 REPORTER_ASSERT(reporter, *color == kGreen, "piecewise: %d, offset: %zu",
483 piecewise, offset);
484 }
485 }
486 }
487}
@ kStatic_GrAccessPattern
Definition: GrTypesPriv.h:428
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
Definition: SkAlign.h:33
size_t bufferUpdateDataPreserveAlignment() const
Definition: GrCaps.h:250
sk_sp< GrGpuBuffer > createBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern accessPattern)
Definition: GrGpu.cpp:393
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
SeparatedVector2 offset