void RenderViewMLGPU::AddItemFrontToBack(LayerMLGPU* aLayer, ItemInfo& aItem) { // We receive items in front-to-back order. Ideally we want to push items // as far back into batches impossible, to ensure the GPU can do a good // job at culling. However we also want to make sure we actually batch // items versus drawing one primitive per pass. // // As a compromise we look at the most 3 recent batches and then give up. // This can be tweaked in the future. static const size_t kMaxSearch = 3; size_t iterations = 0; for (auto iter = mFrontToBack.rbegin(); iter != mFrontToBack.rend(); iter++) { RenderPassMLGPU* pass = (*iter); if (pass->IsCompatible(aItem) && pass->AcceptItem(aItem)) { AL_LOG("RenderView %p added layer %p to pass %p (%d)\n", this, aLayer->GetLayer(), pass, int(pass->GetType())); return; } if (++iterations > kMaxSearch) { break; } } RefPtr<RenderPassMLGPU> pass = RenderPassMLGPU::CreatePass(mBuilder, aItem); if (!pass || !pass->AcceptItem(aItem)) { MOZ_ASSERT_UNREACHABLE("Could not build a pass for item!"); return; } AL_LOG("RenderView %p added layer %p to new pass %p (%d)\n", this, aLayer->GetLayer(), pass.get(), int(pass->GetType())); mFrontToBack.push_back(pass); }
void RenderViewMLGPU::AddItemBackToFront(LayerMLGPU* aLayer, ItemInfo& aItem) { // We receive layers in front-to-back order, but there are two cases when we // actually draw back-to-front: when the depth buffer is disabled, or when // using the depth buffer and the item has transparent pixels (and therefore // requires blending). In these cases we will build vertex and constant // buffers in reverse, as well as execute batches in reverse, to ensure the // correct ordering. // // Note: We limit the number of batches we search through, since it's better // to add new draw calls than spend too much time finding compatible // batches further down. static const size_t kMaxSearch = 10; size_t iterations = 0; for (auto iter = mBackToFront.begin(); iter != mBackToFront.end(); iter++) { RenderPassMLGPU* pass = (*iter); if (pass->IsCompatible(aItem) && pass->AcceptItem(aItem)) { AL_LOG("RenderView %p added layer %p to pass %p (%d)\n", this, aLayer->GetLayer(), pass, int(pass->GetType())); return; } if (pass->Intersects(aItem)) { break; } if (++iterations > kMaxSearch) { break; } } RefPtr<RenderPassMLGPU> pass = RenderPassMLGPU::CreatePass(mBuilder, aItem); if (!pass || !pass->AcceptItem(aItem)) { MOZ_ASSERT_UNREACHABLE("Could not build a pass for item!"); return; } AL_LOG("RenderView %p added layer %p to new pass %p (%d)\n", this, aLayer->GetLayer(), pass.get(), int(pass->GetType())); mBackToFront.push_front(pass); }