-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transfer approx terrain heights to workers instead of requesting #6716
Changes from all commits
f79da82
dc1abee
103a75a
925c011
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
define([ | ||
'../Core/ApproximateTerrainHeights', | ||
'../Core/BoundingSphere', | ||
'../Core/Cartesian2', | ||
'../Core/Cartesian3', | ||
|
@@ -42,6 +43,7 @@ define([ | |
'./SceneMode', | ||
'./ShadowMode' | ||
], function( | ||
ApproximateTerrainHeights, | ||
BoundingSphere, | ||
Cartesian2, | ||
Cartesian3, | ||
|
@@ -1119,57 +1121,79 @@ define([ | |
}); | ||
} | ||
|
||
var transferTerrainHeightsPromise; | ||
if (!defined(createGeometryTaskProcessors)) { | ||
createGeometryTaskProcessors = new Array(numberOfCreationWorkers); | ||
for (i = 0; i < numberOfCreationWorkers; i++) { | ||
createGeometryTaskProcessors[i] = new TaskProcessor('createGeometry', Number.POSITIVE_INFINITY); | ||
} | ||
// Push tasks transferring the JSON to the workers. | ||
transferTerrainHeightsPromise = ApproximateTerrainHeights.initialize() | ||
.then(function() { | ||
var terrainHeightsString = JSON.stringify(ApproximateTerrainHeights._terrainHeights); | ||
var workerTerrainHeightsPromises = new Array(numberOfCreationWorkers); | ||
for (i = 0; i < numberOfCreationWorkers; i++) { | ||
workerTerrainHeightsPromises[i] = createGeometryTaskProcessors[i].scheduleTask({ | ||
subTasks : [ | ||
{ | ||
moduleName : 'parseTerrainHeights', | ||
geometry : terrainHeightsString | ||
} | ||
] | ||
}); | ||
} | ||
return when.all(workerTerrainHeightsPromises); | ||
}); | ||
} else { | ||
transferTerrainHeightsPromise = when(); | ||
} | ||
|
||
var subTask; | ||
subTasks = subdivideArray(subTasks, numberOfCreationWorkers); | ||
|
||
for (i = 0; i < subTasks.length; i++) { | ||
var packedLength = 0; | ||
var workerSubTasks = subTasks[i]; | ||
var workerSubTasksLength = workerSubTasks.length; | ||
for (j = 0; j < workerSubTasksLength; ++j) { | ||
subTask = workerSubTasks[j]; | ||
geometry = subTask.geometry; | ||
if (defined(geometry.constructor.pack)) { | ||
subTask.offset = packedLength; | ||
packedLength += defaultValue(geometry.constructor.packedLength, geometry.packedLength); | ||
} | ||
} | ||
|
||
var subTaskTransferableObjects; | ||
|
||
if (packedLength > 0) { | ||
var array = new Float64Array(packedLength); | ||
subTaskTransferableObjects = [array.buffer]; | ||
transferTerrainHeightsPromise.then(function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note to reviewer: diff tool needs to chill here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding the query param |
||
var subTask; | ||
subTasks = subdivideArray(subTasks, numberOfCreationWorkers); | ||
|
||
for (i = 0; i < subTasks.length; i++) { | ||
var packedLength = 0; | ||
var workerSubTasks = subTasks[i]; | ||
var workerSubTasksLength = workerSubTasks.length; | ||
for (j = 0; j < workerSubTasksLength; ++j) { | ||
subTask = workerSubTasks[j]; | ||
geometry = subTask.geometry; | ||
if (defined(geometry.constructor.pack)) { | ||
geometry.constructor.pack(geometry, array, subTask.offset); | ||
subTask.geometry = array; | ||
subTask.offset = packedLength; | ||
packedLength += defaultValue(geometry.constructor.packedLength, geometry.packedLength); | ||
} | ||
} | ||
} | ||
|
||
promises.push(createGeometryTaskProcessors[i].scheduleTask({ | ||
subTasks : subTasks[i] | ||
}, subTaskTransferableObjects)); | ||
} | ||
var subTaskTransferableObjects; | ||
|
||
primitive._state = PrimitiveState.CREATING; | ||
if (packedLength > 0) { | ||
var array = new Float64Array(packedLength); | ||
subTaskTransferableObjects = [array.buffer]; | ||
|
||
when.all(promises, function(results) { | ||
primitive._createGeometryResults = results; | ||
primitive._state = PrimitiveState.CREATED; | ||
}).otherwise(function(error) { | ||
setReady(primitive, frameState, PrimitiveState.FAILED, error); | ||
for (j = 0; j < workerSubTasksLength; ++j) { | ||
subTask = workerSubTasks[j]; | ||
geometry = subTask.geometry; | ||
if (defined(geometry.constructor.pack)) { | ||
geometry.constructor.pack(geometry, array, subTask.offset); | ||
subTask.geometry = array; | ||
} | ||
} | ||
} | ||
|
||
promises.push(createGeometryTaskProcessors[i].scheduleTask({ | ||
subTasks : subTasks[i] | ||
}, subTaskTransferableObjects)); | ||
} | ||
|
||
primitive._state = PrimitiveState.CREATING; | ||
|
||
when.all(promises, function(results) { | ||
primitive._createGeometryResults = results; | ||
primitive._state = PrimitiveState.CREATED; | ||
}).otherwise(function(error) { | ||
setReady(primitive, frameState, PrimitiveState.FAILED, error); | ||
}); | ||
}); | ||
} else if (primitive._state === PrimitiveState.CREATED) { | ||
var transferableObjects = []; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure this is a good idea, did we time this? I’m not sure why we didn’t just make everything work on the worker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not terrible, even on my chromebook-grade machine this is typically under 50 ms according to simple
console.time
wrapping. I think it's swallowed by the rest of worker spinup, if that's anywhere near as slow as it is in Node. Keep in mind that the JSON parse on the worker side is something that has to happen even if the worker's requesting the terrain heights instead.We could also hold the string on the main thread alongside the parsed version, then release it after workers are spun up... I'll go ahead and add that right after I get CI passing on Travis again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you only timed the Stringify, then you are missing the part where it gets sent over to the worker. For a string, that's probably not a lot of overhead though. However, why wouldn't just making getModuleUrl work in workers be a better solution? I feel like this another bug like this will pop up again in the future the next time we want to do something with a url on a worker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this would also get us around the test failure that I keep running into on Travis in this PR...