| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 virtual void SetStateFromTypedParam(RendererCB* renderer, | 434 virtual void SetStateFromTypedParam(RendererCB* renderer, |
| 435 ParamInteger* param) const { | 435 ParamInteger* param) const { |
| 436 bit_field::Set(value_, BlendEqToCB(param->value())); | 436 bit_field::Set(value_, BlendEqToCB(param->value())); |
| 437 *dirty_ = true; | 437 *dirty_ = true; |
| 438 } | 438 } |
| 439 private: | 439 private: |
| 440 uint32 *value_; | 440 uint32 *value_; |
| 441 bool *dirty_; | 441 bool *dirty_; |
| 442 }; | 442 }; |
| 443 | 443 |
| 444 // A handler that sets the blending color. | |
| 445 // Parameters: | |
| 446 // args: a pointer to the arguments. | |
| 447 // dirty: a pointer to the dirty bit. | |
| 448 class BlendColorStateHandler : public TypedStateHandler<ParamFloat4> { | |
| 449 public: | |
| 450 BlendColorStateHandler(CommandBufferEntry *args, bool *dirty) | |
| 451 : args_(args), | |
| 452 dirty_(dirty) { | |
| 453 } | |
| 454 | |
| 455 virtual void SetStateFromTypedParam(RendererCB* renderer, | |
| 456 ParamFloat4* param) const { | |
| 457 Float4 value = param->value(); | |
| 458 args_[0].value_float = value[0]; | |
| 459 args_[1].value_float = value[1]; | |
| 460 args_[2].value_float = value[2]; | |
| 461 args_[3].value_float = value[3]; | |
| 462 *dirty_ = true; | |
| 463 } | |
| 464 private: | |
| 465 CommandBufferEntry *args_; | |
| 466 bool *dirty_; | |
| 467 }; | |
| 468 | |
| 469 // Adds all the state handlers for all the states. The list of handlers must | 444 // Adds all the state handlers for all the states. The list of handlers must |
| 470 // match in names and types the list in Renderer::AddDefaultStates() | 445 // match in names and types the list in Renderer::AddDefaultStates() |
| 471 // (in renderer.cc). | 446 // (in renderer.cc). |
| 472 void RendererCB::StateManager::AddStateHandlers(RendererCB *renderer) { | 447 void RendererCB::StateManager::AddStateHandlers(RendererCB *renderer) { |
| 473 // Point/Line raster | 448 // Point/Line raster |
| 474 { | 449 { |
| 475 using command_buffer::set_point_line_raster::LineSmoothEnable; | 450 using command_buffer::set_point_line_raster::LineSmoothEnable; |
| 476 using command_buffer::set_point_line_raster::PointSpriteEnable; | 451 using command_buffer::set_point_line_raster::PointSpriteEnable; |
| 477 bool *dirty = point_line_helper_.dirty_ptr(); | 452 bool *dirty = point_line_helper_.dirty_ptr(); |
| 478 uint32 *arg0 = &(point_line_helper_.args()[0].value_uint32); | 453 command_buffer::cmd::SetPointLineRaster& cmd = |
| 479 float *arg1 = &(point_line_helper_.args()[1].value_float); | 454 point_line_helper_.command(); |
| 480 renderer->AddStateHandler( | 455 renderer->AddStateHandler( |
| 481 State::kLineSmoothEnableParamName, | 456 State::kLineSmoothEnableParamName, |
| 482 new EnableStateHandler<LineSmoothEnable>(arg0, dirty)); | 457 new EnableStateHandler<LineSmoothEnable>(&cmd.fixme0, dirty)); |
| 483 renderer->AddStateHandler( | 458 renderer->AddStateHandler( |
| 484 State::kPointSpriteEnableParamName, | 459 State::kPointSpriteEnableParamName, |
| 485 new EnableStateHandler<PointSpriteEnable>(arg0, dirty)); | 460 new EnableStateHandler<PointSpriteEnable>(&cmd.fixme0, dirty)); |
| 486 renderer->AddStateHandler(State::kPointSizeParamName, | 461 renderer->AddStateHandler(State::kPointSizeParamName, |
| 487 new ValueStateHandler<ParamFloat>(arg1, dirty)); | 462 new ValueStateHandler<ParamFloat>( |
| 463 &cmd.point_size, dirty)); |
| 488 } | 464 } |
| 489 | 465 |
| 490 // Polygon Raster | 466 // Polygon Raster |
| 491 { | 467 { |
| 492 bool *dirty = poly_raster_helper_.dirty_ptr(); | 468 bool *dirty = poly_raster_helper_.dirty_ptr(); |
| 493 uint32 *arg = &(poly_raster_helper_.args()[0].value_uint32); | 469 command_buffer::cmd::SetPolygonRaster& cmd = |
| 470 poly_raster_helper_.command(); |
| 494 renderer->AddStateHandler(State::kCullModeParamName, | 471 renderer->AddStateHandler(State::kCullModeParamName, |
| 495 new CullModeStateHandler(arg, dirty)); | 472 new CullModeStateHandler(&cmd.fixme0, dirty)); |
| 496 renderer->AddStateHandler(State::kFillModeParamName, | 473 renderer->AddStateHandler(State::kFillModeParamName, |
| 497 new FillModeStateHandler(arg, dirty)); | 474 new FillModeStateHandler(&cmd.fixme0, dirty)); |
| 498 } | 475 } |
| 499 | 476 |
| 500 // Polygon Offset | 477 // Polygon Offset |
| 501 { | 478 { |
| 502 bool *dirty = poly_offset_helper_.dirty_ptr(); | 479 bool *dirty = poly_offset_helper_.dirty_ptr(); |
| 503 float *arg0 = &(poly_offset_helper_.args()[0].value_float); | 480 command_buffer::cmd::SetPolygonOffset& cmd = |
| 504 float *arg1 = &(poly_offset_helper_.args()[1].value_float); | 481 poly_offset_helper_.command(); |
| 505 renderer->AddStateHandler(State::kPolygonOffset1ParamName, | 482 renderer->AddStateHandler( |
| 506 new ValueStateHandler<ParamFloat>(arg0, dirty)); | 483 State::kPolygonOffset1ParamName, |
| 507 renderer->AddStateHandler(State::kPolygonOffset2ParamName, | 484 new ValueStateHandler<ParamFloat>(&cmd.slope_factor, dirty)); |
| 508 new ValueStateHandler<ParamFloat>(arg1, dirty)); | 485 renderer->AddStateHandler( |
| 486 State::kPolygonOffset2ParamName, |
| 487 new ValueStateHandler<ParamFloat>(&cmd.units, dirty)); |
| 509 } | 488 } |
| 510 | 489 |
| 511 // Alpha test | 490 // Alpha test |
| 512 { | 491 { |
| 513 using command_buffer::set_alpha_test::Enable; | 492 using command_buffer::set_alpha_test::Enable; |
| 514 using command_buffer::set_alpha_test::Func; | 493 using command_buffer::set_alpha_test::Func; |
| 494 command_buffer::cmd::SetAlphaTest& cmd = alpha_test_helper_.command(); |
| 515 bool *dirty = alpha_test_helper_.dirty_ptr(); | 495 bool *dirty = alpha_test_helper_.dirty_ptr(); |
| 516 uint32 *arg0 = &(alpha_test_helper_.args()[0].value_uint32); | 496 renderer->AddStateHandler( |
| 517 float *arg1 = &(alpha_test_helper_.args()[1].value_float); | 497 State::kAlphaTestEnableParamName, |
| 518 renderer->AddStateHandler(State::kAlphaTestEnableParamName, | 498 new EnableStateHandler<Enable>(&cmd.fixme0, dirty)); |
| 519 new EnableStateHandler<Enable>(arg0, dirty)); | 499 renderer->AddStateHandler( |
| 520 renderer->AddStateHandler(State::kAlphaComparisonFunctionParamName, | 500 State::kAlphaComparisonFunctionParamName, |
| 521 new ComparisonStateHandler<Func>(arg0, dirty)); | 501 new ComparisonStateHandler<Func>(&cmd.fixme0, dirty)); |
| 522 renderer->AddStateHandler(State::kAlphaReferenceParamName, | 502 renderer->AddStateHandler( |
| 523 new ValueStateHandler<ParamFloat>(arg1, dirty)); | 503 State::kAlphaReferenceParamName, |
| 504 new ValueStateHandler<ParamFloat>(&cmd.value, dirty)); |
| 524 } | 505 } |
| 525 | 506 |
| 526 // Depth Test | 507 // Depth Test |
| 527 { | 508 { |
| 528 using command_buffer::set_depth_test::Enable; | 509 using command_buffer::set_depth_test::Enable; |
| 529 using command_buffer::set_depth_test::WriteEnable; | 510 using command_buffer::set_depth_test::WriteEnable; |
| 530 using command_buffer::set_depth_test::Func; | 511 using command_buffer::set_depth_test::Func; |
| 531 bool *dirty = depth_test_helper_.dirty_ptr(); | 512 bool *dirty = depth_test_helper_.dirty_ptr(); |
| 532 uint32 *arg = &(depth_test_helper_.args()[0].value_uint32); | 513 command_buffer::cmd::SetDepthTest& cmd = depth_test_helper_.command(); |
| 533 renderer->AddStateHandler(State::kZWriteEnableParamName, | 514 renderer->AddStateHandler( |
| 534 new EnableStateHandler<WriteEnable>(arg, dirty)); | 515 State::kZWriteEnableParamName, |
| 535 renderer->AddStateHandler(State::kZEnableParamName, | 516 new EnableStateHandler<WriteEnable>(&cmd.fixme0, dirty)); |
| 536 new EnableStateHandler<Enable>(arg, dirty)); | 517 renderer->AddStateHandler( |
| 537 renderer->AddStateHandler(State::kZComparisonFunctionParamName, | 518 State::kZEnableParamName, |
| 538 new ComparisonStateHandler<Func>(arg, dirty)); | 519 new EnableStateHandler<Enable>(&cmd.fixme0, dirty)); |
| 520 renderer->AddStateHandler( |
| 521 State::kZComparisonFunctionParamName, |
| 522 new ComparisonStateHandler<Func>(&cmd.fixme0, dirty)); |
| 539 } | 523 } |
| 540 | 524 |
| 541 // Stencil Test | 525 // Stencil Test |
| 542 { | 526 { |
| 543 using command_buffer::set_stencil_test::Enable; | 527 using command_buffer::set_stencil_test::Enable; |
| 544 using command_buffer::set_stencil_test::SeparateCCW; | 528 using command_buffer::set_stencil_test::SeparateCCW; |
| 545 using command_buffer::set_stencil_test::WriteMask; | 529 using command_buffer::set_stencil_test::WriteMask; |
| 546 using command_buffer::set_stencil_test::CompareMask; | 530 using command_buffer::set_stencil_test::CompareMask; |
| 547 using command_buffer::set_stencil_test::ReferenceValue; | 531 using command_buffer::set_stencil_test::ReferenceValue; |
| 548 using command_buffer::set_stencil_test::CWFunc; | 532 using command_buffer::set_stencil_test::CWFunc; |
| 549 using command_buffer::set_stencil_test::CWPassOp; | 533 using command_buffer::set_stencil_test::CWPassOp; |
| 550 using command_buffer::set_stencil_test::CWFailOp; | 534 using command_buffer::set_stencil_test::CWFailOp; |
| 551 using command_buffer::set_stencil_test::CWZFailOp; | 535 using command_buffer::set_stencil_test::CWZFailOp; |
| 552 using command_buffer::set_stencil_test::CCWFunc; | 536 using command_buffer::set_stencil_test::CCWFunc; |
| 553 using command_buffer::set_stencil_test::CCWPassOp; | 537 using command_buffer::set_stencil_test::CCWPassOp; |
| 554 using command_buffer::set_stencil_test::CCWFailOp; | 538 using command_buffer::set_stencil_test::CCWFailOp; |
| 555 using command_buffer::set_stencil_test::CCWZFailOp; | 539 using command_buffer::set_stencil_test::CCWZFailOp; |
| 556 bool *dirty = stencil_test_helper_.dirty_ptr(); | 540 bool *dirty = stencil_test_helper_.dirty_ptr(); |
| 557 uint32 *arg0 = &(stencil_test_helper_.args()[0].value_uint32); | 541 command_buffer::cmd::SetStencilTest& cmd = stencil_test_helper_.command(); |
| 558 uint32 *arg1 = &(stencil_test_helper_.args()[1].value_uint32); | 542 renderer->AddStateHandler( |
| 559 renderer->AddStateHandler(State::kStencilEnableParamName, | 543 State::kStencilEnableParamName, |
| 560 new EnableStateHandler<Enable>(arg0, dirty)); | 544 new EnableStateHandler<Enable>(&cmd.fixme0, dirty)); |
| 561 renderer->AddStateHandler(State::kTwoSidedStencilEnableParamName, | 545 renderer->AddStateHandler( |
| 562 new EnableStateHandler<SeparateCCW>(arg0, dirty)); | 546 State::kTwoSidedStencilEnableParamName, |
| 547 new EnableStateHandler<SeparateCCW>(&cmd.fixme0, dirty)); |
| 563 renderer->AddStateHandler( | 548 renderer->AddStateHandler( |
| 564 State::kStencilReferenceParamName, | 549 State::kStencilReferenceParamName, |
| 565 new BitFieldStateHandler<ReferenceValue>(arg0, dirty)); | 550 new BitFieldStateHandler<ReferenceValue>(&cmd.fixme0, dirty)); |
| 566 renderer->AddStateHandler( | 551 renderer->AddStateHandler( |
| 567 State::kStencilMaskParamName, | 552 State::kStencilMaskParamName, |
| 568 new BitFieldStateHandler<CompareMask>(arg0, dirty)); | 553 new BitFieldStateHandler<CompareMask>(&cmd.fixme0, dirty)); |
| 569 renderer->AddStateHandler(State::kStencilWriteMaskParamName, | 554 renderer->AddStateHandler( |
| 570 new BitFieldStateHandler<WriteMask>(arg0, dirty)); | 555 State::kStencilWriteMaskParamName, |
| 556 new BitFieldStateHandler<WriteMask>(&cmd.fixme0, dirty)); |
| 571 | 557 |
| 572 renderer->AddStateHandler(State::kStencilComparisonFunctionParamName, | 558 renderer->AddStateHandler( |
| 573 new ComparisonStateHandler<CWFunc>(arg1, dirty)); | 559 State::kStencilComparisonFunctionParamName, |
| 574 renderer->AddStateHandler(State::kStencilPassOperationParamName, | 560 new ComparisonStateHandler<CWFunc>(&cmd.fixme1, dirty)); |
| 575 new StencilOpStateHandler<CWPassOp>(arg1, dirty)); | 561 renderer->AddStateHandler( |
| 576 renderer->AddStateHandler(State::kStencilFailOperationParamName, | 562 State::kStencilPassOperationParamName, |
| 577 new StencilOpStateHandler<CWFailOp>(arg1, dirty)); | 563 new StencilOpStateHandler<CWPassOp>(&cmd.fixme1, dirty)); |
| 564 renderer->AddStateHandler( |
| 565 State::kStencilFailOperationParamName, |
| 566 new StencilOpStateHandler<CWFailOp>(&cmd.fixme1, dirty)); |
| 578 renderer->AddStateHandler( | 567 renderer->AddStateHandler( |
| 579 State::kStencilZFailOperationParamName, | 568 State::kStencilZFailOperationParamName, |
| 580 new StencilOpStateHandler<CWZFailOp>(arg1, dirty)); | 569 new StencilOpStateHandler<CWZFailOp>(&cmd.fixme1, dirty)); |
| 581 | 570 |
| 582 renderer->AddStateHandler(State::kCCWStencilComparisonFunctionParamName, | 571 renderer->AddStateHandler( |
| 583 new ComparisonStateHandler<CCWFunc>(arg1, dirty)); | 572 State::kCCWStencilComparisonFunctionParamName, |
| 573 new ComparisonStateHandler<CCWFunc>(&cmd.fixme1, dirty)); |
| 574 |
| 584 renderer->AddStateHandler( | 575 renderer->AddStateHandler( |
| 585 State::kCCWStencilPassOperationParamName, | 576 State::kCCWStencilPassOperationParamName, |
| 586 new StencilOpStateHandler<CCWPassOp>(arg1, dirty)); | 577 new StencilOpStateHandler<CCWPassOp>(&cmd.fixme1, dirty)); |
| 587 renderer->AddStateHandler( | 578 renderer->AddStateHandler( |
| 588 State::kCCWStencilFailOperationParamName, | 579 State::kCCWStencilFailOperationParamName, |
| 589 new StencilOpStateHandler<CCWFailOp>(arg1, dirty)); | 580 new StencilOpStateHandler<CCWFailOp>(&cmd.fixme1, dirty)); |
| 590 renderer->AddStateHandler( | 581 renderer->AddStateHandler( |
| 591 State::kCCWStencilZFailOperationParamName, | 582 State::kCCWStencilZFailOperationParamName, |
| 592 new StencilOpStateHandler<CCWZFailOp>(arg1, dirty)); | 583 new StencilOpStateHandler<CCWZFailOp>(&cmd.fixme1, dirty)); |
| 593 } | 584 } |
| 594 | 585 |
| 595 // Blending | 586 // Blending |
| 596 { | 587 { |
| 597 using command_buffer::set_blending::Enable; | 588 using command_buffer::set_blending::Enable; |
| 598 using command_buffer::set_blending::SeparateAlpha; | 589 using command_buffer::set_blending::SeparateAlpha; |
| 599 using command_buffer::set_blending::ColorEq; | 590 using command_buffer::set_blending::ColorEq; |
| 600 using command_buffer::set_blending::ColorSrcFunc; | 591 using command_buffer::set_blending::ColorSrcFunc; |
| 601 using command_buffer::set_blending::ColorDstFunc; | 592 using command_buffer::set_blending::ColorDstFunc; |
| 602 using command_buffer::set_blending::AlphaEq; | 593 using command_buffer::set_blending::AlphaEq; |
| 603 using command_buffer::set_blending::AlphaSrcFunc; | 594 using command_buffer::set_blending::AlphaSrcFunc; |
| 604 using command_buffer::set_blending::AlphaDstFunc; | 595 using command_buffer::set_blending::AlphaDstFunc; |
| 605 bool *dirty = blending_helper_.dirty_ptr(); | 596 bool *dirty = blending_helper_.dirty_ptr(); |
| 606 uint32 *arg = &(blending_helper_.args()[0].value_uint32); | 597 command_buffer::cmd::SetBlending& cmd = blending_helper_.command(); |
| 607 renderer->AddStateHandler(State::kAlphaBlendEnableParamName, | 598 renderer->AddStateHandler( |
| 608 new EnableStateHandler<Enable>(arg, dirty)); | 599 State::kAlphaBlendEnableParamName, |
| 600 new EnableStateHandler<Enable>(&cmd.fixme0, dirty)); |
| 609 renderer->AddStateHandler( | 601 renderer->AddStateHandler( |
| 610 State::kSeparateAlphaBlendEnableParamName, | 602 State::kSeparateAlphaBlendEnableParamName, |
| 611 new EnableStateHandler<SeparateAlpha>(arg, dirty)); | 603 new EnableStateHandler<SeparateAlpha>(&cmd.fixme0, dirty)); |
| 612 | 604 |
| 613 renderer->AddStateHandler( | 605 renderer->AddStateHandler( |
| 614 State::kSourceBlendFunctionParamName, | 606 State::kSourceBlendFunctionParamName, |
| 615 new BlendFuncStateHandler<ColorSrcFunc>(arg, dirty)); | 607 new BlendFuncStateHandler<ColorSrcFunc>(&cmd.fixme0, dirty)); |
| 616 renderer->AddStateHandler( | 608 renderer->AddStateHandler( |
| 617 State::kDestinationBlendFunctionParamName, | 609 State::kDestinationBlendFunctionParamName, |
| 618 new BlendFuncStateHandler<ColorDstFunc>(arg, dirty)); | 610 new BlendFuncStateHandler<ColorDstFunc>(&cmd.fixme0, dirty)); |
| 619 renderer->AddStateHandler(State::kBlendEquationParamName, | 611 renderer->AddStateHandler( |
| 620 new BlendEqStateHandler<ColorEq>(arg, dirty)); | 612 State::kBlendEquationParamName, |
| 613 new BlendEqStateHandler<ColorEq>(&cmd.fixme0, dirty)); |
| 621 renderer->AddStateHandler( | 614 renderer->AddStateHandler( |
| 622 State::kSourceBlendAlphaFunctionParamName, | 615 State::kSourceBlendAlphaFunctionParamName, |
| 623 new BlendFuncStateHandler<AlphaSrcFunc>(arg, dirty)); | 616 new BlendFuncStateHandler<AlphaSrcFunc>(&cmd.fixme0, dirty)); |
| 624 renderer->AddStateHandler( | 617 renderer->AddStateHandler( |
| 625 State::kDestinationBlendAlphaFunctionParamName, | 618 State::kDestinationBlendAlphaFunctionParamName, |
| 626 new BlendFuncStateHandler<AlphaDstFunc>(arg, dirty)); | 619 new BlendFuncStateHandler<AlphaDstFunc>(&cmd.fixme0, dirty)); |
| 627 renderer->AddStateHandler(State::kBlendAlphaEquationParamName, | 620 renderer->AddStateHandler( |
| 628 new BlendEqStateHandler<AlphaEq>(arg, dirty)); | 621 State::kBlendAlphaEquationParamName, |
| 622 new BlendEqStateHandler<AlphaEq>(&cmd.fixme0, dirty)); |
| 629 } | 623 } |
| 630 | 624 |
| 631 // Color Write | 625 // Color Write |
| 632 { | 626 { |
| 633 using command_buffer::set_color_write::DitherEnable; | 627 using command_buffer::set_color_write::DitherEnable; |
| 634 using command_buffer::set_color_write::AllColorsMask; | 628 using command_buffer::set_color_write::AllColorsMask; |
| 635 bool *dirty = color_write_helper_.dirty_ptr(); | 629 bool *dirty = color_write_helper_.dirty_ptr(); |
| 636 uint32 *arg = &(color_write_helper_.args()[0].value_uint32); | 630 command_buffer::cmd::SetColorWrite& cmd = color_write_helper_.command(); |
| 637 renderer->AddStateHandler(State::kDitherEnableParamName, | 631 renderer->AddStateHandler( |
| 638 new EnableStateHandler<DitherEnable>(arg, dirty)); | 632 State::kDitherEnableParamName, |
| 633 new EnableStateHandler<DitherEnable>(&cmd.flags, dirty)); |
| 639 renderer->AddStateHandler( | 634 renderer->AddStateHandler( |
| 640 State::kColorWriteEnableParamName, | 635 State::kColorWriteEnableParamName, |
| 641 new ColorWriteStateHandler(arg, dirty)); | 636 new ColorWriteStateHandler(&cmd.flags, dirty)); |
| 642 } | 637 } |
| 643 } | 638 } |
| 644 | 639 |
| 645 void RendererCB::StateManager::ValidateStates(CommandBufferHelper *helper) { | 640 void RendererCB::StateManager::ValidateStates(CommandBufferHelper *helper) { |
| 646 point_line_helper_.Validate(helper); | 641 point_line_helper_.Validate(helper); |
| 647 poly_offset_helper_.Validate(helper); | 642 poly_offset_helper_.Validate(helper); |
| 648 poly_raster_helper_.Validate(helper); | 643 poly_raster_helper_.Validate(helper); |
| 649 alpha_test_helper_.Validate(helper); | 644 alpha_test_helper_.Validate(helper); |
| 650 depth_test_helper_.Validate(helper); | 645 depth_test_helper_.Validate(helper); |
| 651 stencil_test_helper_.Validate(helper); | 646 stencil_test_helper_.Validate(helper); |
| 652 color_write_helper_.Validate(helper); | 647 color_write_helper_.Validate(helper); |
| 653 blending_helper_.Validate(helper); | 648 blending_helper_.Validate(helper); |
| 654 blending_color_helper_.Validate(helper); | |
| 655 } | 649 } |
| 656 | 650 |
| 657 } // namespace o3d | 651 } // namespace o3d |
| OLD | NEW |