Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1104)

Unified Diff: src/gpu/gl/GrGLPathRendering.cpp

Issue 1150243003: Simplify path allocation, clean up resources correctly (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGLPathRendering.h ('k') | tests/NameAllocatorTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLPathRendering.cpp
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 4c9ef86786744b8d4df4fbc276e01e90bfd6178c..3cfec749acbdfb92b79be253c4dd59da15fe7131 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -6,7 +6,6 @@
*/
#include "gl/GrGLPathRendering.h"
-#include "gl/GrGLNameAllocator.h"
#include "gl/GrGLUtil.h"
#include "gl/GrGLGpu.h"
@@ -20,6 +19,9 @@
#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->gpu()->glInterface(), RET, X)
+// Number of paths to allocate per glGenPaths call. The call can be overly slow on command buffer GL
+// implementation. The call has a result value, and thus waiting for the call completion is needed.
+static const GrGLsizei kPathIDPreallocationAmount = 65536;
static const GrGLenum gIndexType2GLType[] = {
GR_GL_UNSIGNED_BYTE,
@@ -60,17 +62,21 @@ static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
}
GrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu)
- : GrPathRendering(gpu) {
+ : GrPathRendering(gpu)
+ , fPreallocatedPathCount(0) {
const GrGLInterface* glInterface = gpu->glInterface();
fCaps.bindFragmentInputSupport =
nullptr != glInterface->fFunctions.fBindFragmentInputLocation;
}
GrGLPathRendering::~GrGLPathRendering() {
+ if (fPreallocatedPathCount > 0) {
+ this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount);
+ }
}
void GrGLPathRendering::abandonGpuResources() {
- fPathNameAllocator.reset(nullptr);
+ fPreallocatedPathCount = 0;
}
void GrGLPathRendering::resetContext() {
@@ -230,54 +236,57 @@ void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
}
GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) {
- if (range > 1) {
- GrGLuint name;
- GL_CALL_RET(name, GenPaths(range));
- return name;
+ SkASSERT(range > 0);
+ GrGLuint firstID;
+ if (fPreallocatedPathCount >= range) {
+ firstID = fFirstPreallocatedPathID;
+ fPreallocatedPathCount -= range;
+ fFirstPreallocatedPathID += range;
+ return firstID;
}
-
- if (nullptr == fPathNameAllocator.get()) {
- static const int range = 65536;
- GrGLuint firstName;
- GL_CALL_RET(firstName, GenPaths(range));
- fPathNameAllocator.reset(new GrGLNameAllocator(firstName, firstName + range));
+ // Allocate range + the amount to fill up preallocation amount. If succeed, either join with
+ // the existing preallocation range or delete the existing and use the new (potentially partial)
+ // preallocation range.
+ GrGLsizei allocAmount = range + (kPathIDPreallocationAmount - fPreallocatedPathCount);
+ if (allocAmount >= range) {
+ GL_CALL_RET(firstID, GenPaths(allocAmount));
+
+ if (firstID != 0) {
+ if (fPreallocatedPathCount > 0 &&
+ firstID == fFirstPreallocatedPathID + fPreallocatedPathCount) {
+ firstID = fFirstPreallocatedPathID;
+ fPreallocatedPathCount += allocAmount - range;
+ fFirstPreallocatedPathID += range;
+ return firstID;
+ }
+
+ if (allocAmount > range) {
+ if (fPreallocatedPathCount > 0) {
+ this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount);
+ }
+ fFirstPreallocatedPathID = firstID + range;
+ fPreallocatedPathCount = allocAmount - range;
+ }
+ // Special case: if allocAmount == range, we have full preallocated range.
+ return firstID;
+ }
}
-
- // When allocating names one at a time, pull from a client-side pool of
- // available names in order to save a round trip to the GL server.
- GrGLuint name = fPathNameAllocator->allocateName();
-
- if (0 == name) {
- // Our reserved path names are all in use. Fall back on GenPaths.
- GL_CALL_RET(name, GenPaths(1));
+ // Failed to allocate with preallocation. Remove existing preallocation and try to allocate just
+ // the range.
+ if (fPreallocatedPathCount > 0) {
+ this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount);
+ fPreallocatedPathCount = 0;
}
- return name;
+ GL_CALL_RET(firstID, GenPaths(range));
+ if (firstID == 0) {
+ SkDebugf("Warning: Failed to allocate path\n");
+ }
+ return firstID;
}
void GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) {
- if (range > 1) {
- // It is not supported to delete names in ranges that were allocated
- // individually using GrGLPathNameAllocator.
- SkASSERT(nullptr == fPathNameAllocator.get() ||
- path + range <= fPathNameAllocator->firstName() ||
- path >= fPathNameAllocator->endName());
- GL_CALL(DeletePaths(path, range));
- return;
- }
-
- if (nullptr == fPathNameAllocator.get() ||
- path < fPathNameAllocator->firstName() ||
- path >= fPathNameAllocator->endName()) {
- // If we aren't inside fPathNameAllocator's range then this name was
- // generated by the GenPaths fallback (or else was never allocated).
- GL_CALL(DeletePaths(path, 1));
- return;
- }
-
- // Make the path empty to save memory, but don't free the name in the driver.
- GL_CALL(PathCommands(path, 0, nullptr, 0, GR_GL_FLOAT, nullptr));
- fPathNameAllocator->free(path);
+ GL_CALL(DeletePaths(path, range));
}
void GrGLPathRendering::flushPathStencilSettings(const GrStencilSettings& stencilSettings) {
« no previous file with comments | « src/gpu/gl/GrGLPathRendering.h ('k') | tests/NameAllocatorTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698