| 34 | } |
| 35 | |
| 36 | std::pair<devicert::AsyncEvent, devicert::AsyncEvent> |
| 37 | DistributedLoadBalancer::renderFrame( |
| 38 | FrameBuffer *_fb, Renderer *_renderer, Camera *camera, World *_world) |
| 39 | { |
| 40 | auto *dfb = dynamic_cast<DistributedFrameBuffer *>(_fb); |
| 41 | if (!dfb) { |
| 42 | throw std::runtime_error( |
| 43 | "Distributed Load Balancer only supports DistributedFrameBuffer!"); |
| 44 | } |
| 45 | |
| 46 | auto *world = dynamic_cast<DistributedWorld *>(_world); |
| 47 | if (!world) { |
| 48 | throw std::runtime_error( |
| 49 | "Distributed Load Balancer only supports DistributedWorld!"); |
| 50 | } |
| 51 | |
| 52 | auto *renderer = dynamic_cast<DistributedRenderer *>(_renderer); |
| 53 | if (!renderer) { |
| 54 | if (world->allRegions.size() == 1) { |
| 55 | renderFrameReplicated(dfb, _renderer, camera, world); |
| 56 | return std::make_pair(devicert::AsyncEvent(), devicert::AsyncEvent()); |
| 57 | } else { |
| 58 | throw std::runtime_error( |
| 59 | "Distributed rendering requires a distributed renderer!"); |
| 60 | } |
| 61 | } |
| 62 | if (dfb->getLastRenderer() != renderer) { |
| 63 | dfb->setTileOperation(renderer->tileOperation(), renderer); |
| 64 | } |
| 65 | |
| 66 | RKCOMMON_IF_TRACING_ENABLED( |
| 67 | rkcommon::tracing::beginEvent("renderFrameDistributed", "DistributedLB")); |
| 68 | |
| 69 | dfb->startNewFrame(renderer->errorThreshold); |
| 70 | void *perFrameData = renderer->beginFrame(dfb, world); |
| 71 | const size_t numRegions = world->allRegions.size(); |
| 72 | |
| 73 | RKCOMMON_IF_TRACING_ENABLED( |
| 74 | rkcommon::tracing::beginEvent("determineTilesForFrame", "DistributedLB")); |
| 75 | |
| 76 | std::vector<std::vector<uint32_t>> regionTileIds(world->myRegionIds.size()); |
| 77 | const vec2i numTiles = dfb->getGlobalNumTiles(); |
| 78 | const vec2i fbSize = dfb->getNumPixels(); |
| 79 | for (size_t i = 0; i < world->myRegionIds.size(); ++i) { |
| 80 | const size_t id = world->myRegionIds[i]; |
| 81 | const auto &r = world->allRegions[id]; |
| 82 | box3f proj = camera->projectBox(r); |
| 83 | box2f screenRegion(vec2f(proj.lower) * fbSize, vec2f(proj.upper) * fbSize); |
| 84 | |
| 85 | // Pad the region a bit |
| 86 | screenRegion.lower = max(screenRegion.lower - TILE_SIZE, vec2f(0.f)); |
| 87 | screenRegion.upper = min(screenRegion.upper + TILE_SIZE, vec2f(fbSize)); |
| 88 | |
| 89 | // Skip regions that are completely behind the camera |
| 90 | if (proj.upper.z < 0.f) { |
| 91 | continue; |
| 92 | } |
| 93 |
nothing calls this directly
no test coverage detected