/* * Prepare a subplan for sharing. This creates a Materialize node, * or marks the existing Materialize or Sort node as shared. After * this, you can call share_prepared_plan() as many times as you * want to share this plan. */ Plan * prepare_plan_for_sharing(PlannerInfo *root, Plan *common) { ShareType stype; Plan *shared = common; bool xslice = false; if (IsA(common, ShareInputScan)) { shared = common->lefttree; } else if(IsA(common, Material)) { Material *m = (Material *) common; Assert(m->share_type == SHARE_NOTSHARED); Assert(m->share_id == SHARE_ID_NOT_SHARED); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } else if (IsA(common, Sort)) { Sort *s = (Sort *) common; Assert(s->share_type == SHARE_NOTSHARED); stype = xslice ? SHARE_SORT_XSLICE : SHARE_SORT; s->share_id = SHARE_ID_NOT_ASSIGNED; s->share_type = stype; } else { Path matpath; Material *m = make_material(common); shared = (Plan *) m; cost_material(&matpath, root, common->total_cost, common->plan_rows, common->plan_width); shared->startup_cost = matpath.startup_cost; shared->total_cost = matpath.total_cost; shared->plan_rows = common->plan_rows; shared->plan_width = common->plan_width; shared->dispatch = common->dispatch; shared->flow = copyObject(common->flow); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } return shared; }
List *share_plan(PlannerInfo *root, Plan *common, int numpartners) { List *shared_nodes = NULL; ShareType stype; Plan *shared = common; bool xslice = false; int i; Assert(numpartners > 0); if(numpartners == 1) { shared_nodes = lappend(shared_nodes, common); return shared_nodes; } if (IsA(common, ShareInputScan)) { shared = common->lefttree; } else if(IsA(common, Material)) { Material *m = (Material *) common; Assert(m->share_type == SHARE_NOTSHARED); Assert(m->share_id == SHARE_ID_NOT_SHARED); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } else if (IsA(common, Sort)) { Sort *s = (Sort *) common; Assert(s->share_type == SHARE_NOTSHARED); stype = xslice ? SHARE_SORT_XSLICE : SHARE_SORT; s->share_id = SHARE_ID_NOT_ASSIGNED; s->share_type = stype; } else { Path matpath; Material *m = make_material(common); shared = (Plan *) m; cost_material(&matpath, root, common->total_cost, common->plan_rows, common->plan_width); shared->startup_cost = matpath.startup_cost; shared->total_cost = matpath.total_cost; shared->plan_rows = common->plan_rows; shared->plan_width = common->plan_width; shared->dispatch = common->dispatch; shared->flow = copyObject(common->flow); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } for(i=0; i<numpartners; ++i) { Plan *p = (Plan *) make_shareinputscan(root, shared); shared_nodes = lappend(shared_nodes, p); } return shared_nodes; }
int main(int argc, char* argv[]) { vector<string> args; for (int i = 1; i < argc; ++i) args.push_back(argv[i]); // !! we should probably move this code somewhere that is not main, but otoh it's kinda nice to have it here // !! also where else would it go anyways? // ***** this is still preliminary, and will probably change significatly ***** int argi = 0; // a little silly REPL loop so that it's easier to test urn // perhaps one day this will happen after it loads the scene so that you can modify that if(args[argi] == "/i") { argi++; urn::eval_context cx; cx.create_std_funcs(); while (true) { string s; cout << "urn> "; getline(cin, s); auto ts = urn::token_stream(istringstream(s)); auto v = urn::value(ts); if (v.type == urn::value::Val) { auto cmd = v.get_val(); if (cmd == "!q") break; else if (cmd == "!x") return 42; } cout << cx.eval(v) << endl; } } auto init_start = chrono::high_resolution_clock::now(); auto ts = urn::token_stream(ifstream(args[argi])); urn::value scene_tlv = urn::value(ts); //requires first cmdline argument to be path to scene file for now auto resolu_b = scene_tlv.named_block_val("resolution"); auto resolution = resolu_b.is_null() ? uvec2(1280, 960) : uvec2(resolu_b[0].get<int64_t>(), resolu_b[1].get<int64_t>()); shared_ptr<plu::texture2d> tx = make_shared<plu::texture2d>( resolution ); auto cam_b = scene_tlv.named_block_val("camera"); auto cam = plu::camera(bk2v3(cam_b.named_block_val("position")), bk2v3(cam_b.named_block_val("target"))); auto smp_cnt = scene_tlv.named_block_val("antialiasing-samples").get<int64_t>(); map<string, shared_ptr<plu::material>> mats; vector<shared_ptr<plu::surface>> surfs; urn::eval_context cx; cx.create_std_funcs(); auto matvs = scene_tlv.named_block_val("materials").get<vector<urn::value>>(); for (int i = 0; i < matvs.size(); ++i) { if (matvs[i].type != urn::value::Def) throw; auto d = matvs[i].get<pair<string, urn::value>>(); mats[d.first] = make_material(cx, d.second); } auto objvs = cx.eval1(scene_tlv.named_block_val("objects")).get<vector<urn::value>>(); for (int i = 0; i < objvs.size();) { auto ot = objvs[i].get_var(); if (ot == "sphere") { auto m = objvs[i + 3]; auto M = m.type == urn::value::Block ? make_material(cx, m) : m.type == urn::value::Id ? mats[m.get_id()] : nullptr; surfs.push_back(make_shared<plu::surfaces::sphere>(bk2v3(cx, objvs[i+1]), cx.eval(objvs[i+2]).get_num(), M)); i += 4; } else if (ot == "box") { auto m = objvs[i + 3]; auto M = m.type == urn::value::Block ? make_material(cx, m) : m.type == urn::value::Id ? mats[m.get_id()] : nullptr; surfs.push_back(make_shared<plu::surfaces::box>(bk2v3(cx, objvs[i + 1]), bk2v3(cx, objvs[i + 2]), M)); i += 4; } } auto s = //new plu::group(surfs); new plu::surfaces::bvh_tree(surfs); plu::renderer r(s, cam, uvec2(64), smp_cnt); auto init_end = chrono::high_resolution_clock::now(); auto render_start = chrono::high_resolution_clock::now(); r.render(tx); auto render_end = chrono::high_resolution_clock::now(); auto init_time = chrono::duration_cast<chrono::milliseconds>(init_end - init_start); // convert to milliseconds b/c humans are bad at big numbers auto render_time = chrono::duration_cast<chrono::milliseconds>(render_end - render_start); ostringstream watermark; watermark << "scene: " << args[0] << endl << "init took: " << init_time.count() << "ms" << endl << "render took: " << render_time.count() << "ms" << endl; #ifdef _DEBUG watermark << "DEBUG" << endl; #else watermark << "RELEASE" << endl; #endif cout << watermark.str(); tx->draw_text(watermark.str(), uvec2(9, 10), vec3(0.2f)); // make a snazzy drop shadow tx->draw_text(watermark.str(), uvec2(8, 8), vec3(1.f, 0.6f, 0)); //draw some text // generate a somewhat unique filename so that we can see our progress ostringstream fns; fns << "image_" << chrono::system_clock::now().time_since_epoch().count() << ".bmp"; tx->write_bmp(fns.str()); //write to image.bmp getchar(); delete s; return 0; }