OLD | NEW |
---|---|
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CC_OUTPUT_SHADER_H_ | 5 #ifndef CC_OUTPUT_SHADER_H_ |
6 #define CC_OUTPUT_SHADER_H_ | 6 #define CC_OUTPUT_SHADER_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 BLEND_MODE_DIFFERENCE, | 52 BLEND_MODE_DIFFERENCE, |
53 BLEND_MODE_EXCLUSION, | 53 BLEND_MODE_EXCLUSION, |
54 BLEND_MODE_MULTIPLY, | 54 BLEND_MODE_MULTIPLY, |
55 BLEND_MODE_HUE, | 55 BLEND_MODE_HUE, |
56 BLEND_MODE_SATURATION, | 56 BLEND_MODE_SATURATION, |
57 BLEND_MODE_COLOR, | 57 BLEND_MODE_COLOR, |
58 BLEND_MODE_LUMINOSITY, | 58 BLEND_MODE_LUMINOSITY, |
59 LAST_BLEND_MODE = BLEND_MODE_LUMINOSITY | 59 LAST_BLEND_MODE = BLEND_MODE_LUMINOSITY |
60 }; | 60 }; |
61 | 61 |
62 struct ShaderLocations { | |
enne (OOO)
2015/03/02 23:34:41
This seems like a good refactoring. Can you split
| |
63 int quad = -1; | |
64 int edge = -1; | |
65 int viewport = -1; | |
66 int mask_sampler = -1; | |
67 int mask_tex_coord_scale = -1; | |
68 int mask_tex_coord_offset = -1; | |
69 int matrix = -1; | |
70 int alpha = -1; | |
71 int color_matrix = -1; | |
72 int color_offset = -1; | |
73 int tex_transform = -1; | |
74 int backdrop = -1; | |
75 int backdrop_rect = -1; | |
76 int original_backdrop = -1; | |
77 }; | |
78 | |
62 // Note: The highp_threshold_cache must be provided by the caller to make | 79 // Note: The highp_threshold_cache must be provided by the caller to make |
63 // the caching multi-thread/context safe in an easy low-overhead manner. | 80 // the caching multi-thread/context safe in an easy low-overhead manner. |
64 // The caller must make sure to clear highp_threshold_cache to 0, so it can be | 81 // The caller must make sure to clear highp_threshold_cache to 0, so it can be |
65 // reinitialized, if a new or different context is used. | 82 // reinitialized, if a new or different context is used. |
66 CC_EXPORT TexCoordPrecision | 83 CC_EXPORT TexCoordPrecision |
67 TexCoordPrecisionRequired(gpu::gles2::GLES2Interface* context, | 84 TexCoordPrecisionRequired(gpu::gles2::GLES2Interface* context, |
68 int* highp_threshold_cache, | 85 int* highp_threshold_cache, |
69 int highp_threshold_min, | 86 int highp_threshold_min, |
70 const gfx::Point& max_coordinate); | 87 const gfx::Point& max_coordinate); |
71 | 88 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 class VertexShaderPosTexTransform { | 166 class VertexShaderPosTexTransform { |
150 public: | 167 public: |
151 VertexShaderPosTexTransform(); | 168 VertexShaderPosTexTransform(); |
152 | 169 |
153 void Init(gpu::gles2::GLES2Interface* context, | 170 void Init(gpu::gles2::GLES2Interface* context, |
154 unsigned program, | 171 unsigned program, |
155 int* base_uniform_index); | 172 int* base_uniform_index); |
156 std::string GetShaderString() const; | 173 std::string GetShaderString() const; |
157 static std::string GetShaderHead(); | 174 static std::string GetShaderHead(); |
158 static std::string GetShaderBody(); | 175 static std::string GetShaderBody(); |
176 void FillLocations(ShaderLocations* locations) const; | |
159 | 177 |
160 int matrix_location() const { return matrix_location_; } | 178 int matrix_location() const { return matrix_location_; } |
161 int tex_transform_location() const { return tex_transform_location_; } | 179 int tex_transform_location() const { return tex_transform_location_; } |
162 int vertex_opacity_location() const { return vertex_opacity_location_; } | 180 int vertex_opacity_location() const { return vertex_opacity_location_; } |
163 | 181 |
164 private: | 182 private: |
165 int matrix_location_; | 183 int matrix_location_; |
166 int tex_transform_location_; | 184 int tex_transform_location_; |
167 int vertex_opacity_location_; | 185 int vertex_opacity_location_; |
168 | 186 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 class VertexShaderQuadTexTransformAA { | 239 class VertexShaderQuadTexTransformAA { |
222 public: | 240 public: |
223 VertexShaderQuadTexTransformAA(); | 241 VertexShaderQuadTexTransformAA(); |
224 | 242 |
225 void Init(gpu::gles2::GLES2Interface* context, | 243 void Init(gpu::gles2::GLES2Interface* context, |
226 unsigned program, | 244 unsigned program, |
227 int* base_uniform_index); | 245 int* base_uniform_index); |
228 std::string GetShaderString() const; | 246 std::string GetShaderString() const; |
229 static std::string GetShaderHead(); | 247 static std::string GetShaderHead(); |
230 static std::string GetShaderBody(); | 248 static std::string GetShaderBody(); |
249 void FillLocations(ShaderLocations* locations) const; | |
231 | 250 |
232 int matrix_location() const { return matrix_location_; } | 251 int matrix_location() const { return matrix_location_; } |
233 int viewport_location() const { return viewport_location_; } | 252 int viewport_location() const { return viewport_location_; } |
234 int quad_location() const { return quad_location_; } | 253 int quad_location() const { return quad_location_; } |
235 int edge_location() const { return edge_location_; } | 254 int edge_location() const { return edge_location_; } |
236 int tex_transform_location() const { return tex_transform_location_; } | 255 int tex_transform_location() const { return tex_transform_location_; } |
237 | 256 |
238 private: | 257 private: |
239 int matrix_location_; | 258 int matrix_location_; |
240 int viewport_location_; | 259 int viewport_location_; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 private: | 337 private: |
319 int matrix_location_; | 338 int matrix_location_; |
320 int tex_matrix_location_; | 339 int tex_matrix_location_; |
321 | 340 |
322 DISALLOW_COPY_AND_ASSIGN(VertexShaderVideoTransform); | 341 DISALLOW_COPY_AND_ASSIGN(VertexShaderVideoTransform); |
323 }; | 342 }; |
324 | 343 |
325 class FragmentTexBlendMode { | 344 class FragmentTexBlendMode { |
326 public: | 345 public: |
327 int backdrop_location() const { return backdrop_location_; } | 346 int backdrop_location() const { return backdrop_location_; } |
347 int original_backdrop_location() const { return original_backdrop_location_; } | |
328 int backdrop_rect_location() const { return backdrop_rect_location_; } | 348 int backdrop_rect_location() const { return backdrop_rect_location_; } |
329 | 349 |
330 BlendMode blend_mode() const { return blend_mode_; } | 350 BlendMode blend_mode() const { return blend_mode_; } |
331 void set_blend_mode(BlendMode blend_mode) { blend_mode_ = blend_mode; } | 351 void set_blend_mode(BlendMode blend_mode) { blend_mode_ = blend_mode; } |
332 bool has_blend_mode() const { return blend_mode_ != BLEND_MODE_NONE; } | 352 bool has_blend_mode() const { return blend_mode_ != BLEND_MODE_NONE; } |
353 void set_mask_for_background(bool mask_for_background) { | |
354 mask_for_background_ = mask_for_background; | |
355 } | |
356 bool mask_for_background() const { return mask_for_background_; } | |
333 | 357 |
334 protected: | 358 protected: |
335 FragmentTexBlendMode(); | 359 FragmentTexBlendMode(); |
336 | 360 |
337 std::string SetBlendModeFunctions(std::string shader_string) const; | 361 std::string SetBlendModeFunctions(std::string shader_string) const; |
338 | 362 |
339 int backdrop_location_; | 363 int backdrop_location_; |
364 int original_backdrop_location_; | |
340 int backdrop_rect_location_; | 365 int backdrop_rect_location_; |
341 | 366 |
342 private: | 367 private: |
343 BlendMode blend_mode_; | 368 BlendMode blend_mode_; |
369 bool mask_for_background_; | |
344 | 370 |
345 std::string GetHelperFunctions() const; | 371 std::string GetHelperFunctions() const; |
346 std::string GetBlendFunction() const; | 372 std::string GetBlendFunction() const; |
347 std::string GetBlendFunctionBodyForRGB() const; | 373 std::string GetBlendFunctionBodyForRGB() const; |
348 }; | 374 }; |
349 | 375 |
350 class FragmentTexAlphaBinding : public FragmentTexBlendMode { | 376 class FragmentTexAlphaBinding : public FragmentTexBlendMode { |
351 public: | 377 public: |
352 FragmentTexAlphaBinding(); | 378 FragmentTexAlphaBinding(); |
353 | 379 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 static std::string GetShaderHead(); | 479 static std::string GetShaderHead(); |
454 static std::string GetShaderBody(); | 480 static std::string GetShaderBody(); |
455 }; | 481 }; |
456 | 482 |
457 class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding { | 483 class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding { |
458 public: | 484 public: |
459 std::string GetShaderString( | 485 std::string GetShaderString( |
460 TexCoordPrecision precision, SamplerType sampler) const; | 486 TexCoordPrecision precision, SamplerType sampler) const; |
461 static std::string GetShaderHead(); | 487 static std::string GetShaderHead(); |
462 static std::string GetShaderBody(); | 488 static std::string GetShaderBody(); |
489 void FillLocations(ShaderLocations* locations) const; | |
463 }; | 490 }; |
464 | 491 |
465 class FragmentShaderRGBATexColorMatrixAlpha | 492 class FragmentShaderRGBATexColorMatrixAlpha |
466 : public FragmentTexColorMatrixAlphaBinding { | 493 : public FragmentTexColorMatrixAlphaBinding { |
467 public: | 494 public: |
468 std::string GetShaderString(TexCoordPrecision precision, | 495 std::string GetShaderString(TexCoordPrecision precision, |
469 SamplerType sampler) const; | 496 SamplerType sampler) const; |
470 static std::string GetShaderHead(); | 497 static std::string GetShaderHead(); |
471 static std::string GetShaderBody(); | 498 static std::string GetShaderBody(); |
499 void FillLocations(ShaderLocations* locations) const; | |
472 }; | 500 }; |
473 | 501 |
474 class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding { | 502 class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding { |
475 public: | 503 public: |
476 std::string GetShaderString( | 504 std::string GetShaderString( |
477 TexCoordPrecision precision, SamplerType sampler) const; | 505 TexCoordPrecision precision, SamplerType sampler) const; |
478 static std::string GetShaderHead(); | 506 static std::string GetShaderHead(); |
479 static std::string GetShaderBody(); | 507 static std::string GetShaderBody(); |
480 }; | 508 }; |
481 | 509 |
(...skipping 27 matching lines...) Expand all Loading... | |
509 public: | 537 public: |
510 FragmentShaderRGBATexAlphaAA(); | 538 FragmentShaderRGBATexAlphaAA(); |
511 | 539 |
512 void Init(gpu::gles2::GLES2Interface* context, | 540 void Init(gpu::gles2::GLES2Interface* context, |
513 unsigned program, | 541 unsigned program, |
514 int* base_uniform_index); | 542 int* base_uniform_index); |
515 std::string GetShaderString( | 543 std::string GetShaderString( |
516 TexCoordPrecision precision, SamplerType sampler) const; | 544 TexCoordPrecision precision, SamplerType sampler) const; |
517 static std::string GetShaderHead(); | 545 static std::string GetShaderHead(); |
518 static std::string GetShaderBody(); | 546 static std::string GetShaderBody(); |
547 void FillLocations(ShaderLocations* locations) const; | |
519 | 548 |
520 int alpha_location() const { return alpha_location_; } | 549 int alpha_location() const { return alpha_location_; } |
521 int sampler_location() const { return sampler_location_; } | 550 int sampler_location() const { return sampler_location_; } |
522 | 551 |
523 private: | 552 private: |
524 int sampler_location_; | 553 int sampler_location_; |
525 int alpha_location_; | 554 int alpha_location_; |
526 | 555 |
527 DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaAA); | 556 DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaAA); |
528 }; | 557 }; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 static std::string GetShaderHead(); | 595 static std::string GetShaderHead(); |
567 static std::string GetShaderBody(); | 596 static std::string GetShaderBody(); |
568 }; | 597 }; |
569 | 598 |
570 class FragmentShaderRGBATexAlphaMask : public FragmentTexBlendMode { | 599 class FragmentShaderRGBATexAlphaMask : public FragmentTexBlendMode { |
571 public: | 600 public: |
572 FragmentShaderRGBATexAlphaMask(); | 601 FragmentShaderRGBATexAlphaMask(); |
573 std::string GetShaderString( | 602 std::string GetShaderString( |
574 TexCoordPrecision precision, SamplerType sampler) const; | 603 TexCoordPrecision precision, SamplerType sampler) const; |
575 static std::string GetShaderHead(); | 604 static std::string GetShaderHead(); |
576 static std::string GetShaderBody(); | 605 static std::string GetShaderBody(bool mask_for_background); |
577 | 606 void FillLocations(ShaderLocations* locations) const; |
578 void Init(gpu::gles2::GLES2Interface* context, | 607 void Init(gpu::gles2::GLES2Interface* context, |
579 unsigned program, | 608 unsigned program, |
580 int* base_uniform_index); | 609 int* base_uniform_index); |
581 int alpha_location() const { return alpha_location_; } | 610 int alpha_location() const { return alpha_location_; } |
582 int sampler_location() const { return sampler_location_; } | 611 int sampler_location() const { return sampler_location_; } |
583 int mask_sampler_location() const { return mask_sampler_location_; } | 612 int mask_sampler_location() const { return mask_sampler_location_; } |
584 int mask_tex_coord_scale_location() const { | 613 int mask_tex_coord_scale_location() const { |
585 return mask_tex_coord_scale_location_; | 614 return mask_tex_coord_scale_location_; |
586 } | 615 } |
587 int mask_tex_coord_offset_location() const { | 616 int mask_tex_coord_offset_location() const { |
588 return mask_tex_coord_offset_location_; | 617 return mask_tex_coord_offset_location_; |
589 } | 618 } |
590 | 619 |
591 private: | 620 private: |
592 int sampler_location_; | 621 int sampler_location_; |
593 int mask_sampler_location_; | 622 int mask_sampler_location_; |
594 int alpha_location_; | 623 int alpha_location_; |
595 int mask_tex_coord_scale_location_; | 624 int mask_tex_coord_scale_location_; |
596 int mask_tex_coord_offset_location_; | 625 int mask_tex_coord_offset_location_; |
597 | 626 |
598 DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMask); | 627 DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMask); |
599 }; | 628 }; |
600 | 629 |
601 class FragmentShaderRGBATexAlphaMaskAA : public FragmentTexBlendMode { | 630 class FragmentShaderRGBATexAlphaMaskAA : public FragmentTexBlendMode { |
602 public: | 631 public: |
603 FragmentShaderRGBATexAlphaMaskAA(); | 632 FragmentShaderRGBATexAlphaMaskAA(); |
604 std::string GetShaderString( | 633 std::string GetShaderString( |
605 TexCoordPrecision precision, SamplerType sampler) const; | 634 TexCoordPrecision precision, SamplerType sampler) const; |
606 static std::string GetShaderHead(); | 635 static std::string GetShaderHead(); |
607 static std::string GetShaderBody(); | 636 static std::string GetShaderBody(bool mask_for_background); |
608 | 637 void FillLocations(ShaderLocations* locations) const; |
609 void Init(gpu::gles2::GLES2Interface* context, | 638 void Init(gpu::gles2::GLES2Interface* context, |
610 unsigned program, | 639 unsigned program, |
611 int* base_uniform_index); | 640 int* base_uniform_index); |
612 int alpha_location() const { return alpha_location_; } | 641 int alpha_location() const { return alpha_location_; } |
613 int sampler_location() const { return sampler_location_; } | 642 int sampler_location() const { return sampler_location_; } |
614 int mask_sampler_location() const { return mask_sampler_location_; } | 643 int mask_sampler_location() const { return mask_sampler_location_; } |
615 int mask_tex_coord_scale_location() const { | 644 int mask_tex_coord_scale_location() const { |
616 return mask_tex_coord_scale_location_; | 645 return mask_tex_coord_scale_location_; |
617 } | 646 } |
618 int mask_tex_coord_offset_location() const { | 647 int mask_tex_coord_offset_location() const { |
(...skipping 10 matching lines...) Expand all Loading... | |
629 DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMaskAA); | 658 DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMaskAA); |
630 }; | 659 }; |
631 | 660 |
632 class FragmentShaderRGBATexAlphaMaskColorMatrixAA | 661 class FragmentShaderRGBATexAlphaMaskColorMatrixAA |
633 : public FragmentTexBlendMode { | 662 : public FragmentTexBlendMode { |
634 public: | 663 public: |
635 FragmentShaderRGBATexAlphaMaskColorMatrixAA(); | 664 FragmentShaderRGBATexAlphaMaskColorMatrixAA(); |
636 std::string GetShaderString( | 665 std::string GetShaderString( |
637 TexCoordPrecision precision, SamplerType sampler) const; | 666 TexCoordPrecision precision, SamplerType sampler) const; |
638 static std::string GetShaderHead(); | 667 static std::string GetShaderHead(); |
639 static std::string GetShaderBody(); | 668 static std::string GetShaderBody(bool mask_for_background); |
640 | 669 void FillLocations(ShaderLocations* locations) const; |
641 void Init(gpu::gles2::GLES2Interface* context, | 670 void Init(gpu::gles2::GLES2Interface* context, |
642 unsigned program, | 671 unsigned program, |
643 int* base_uniform_index); | 672 int* base_uniform_index); |
644 int alpha_location() const { return alpha_location_; } | 673 int alpha_location() const { return alpha_location_; } |
645 int sampler_location() const { return sampler_location_; } | 674 int sampler_location() const { return sampler_location_; } |
646 int mask_sampler_location() const { return mask_sampler_location_; } | 675 int mask_sampler_location() const { return mask_sampler_location_; } |
647 int mask_tex_coord_scale_location() const { | 676 int mask_tex_coord_scale_location() const { |
648 return mask_tex_coord_scale_location_; | 677 return mask_tex_coord_scale_location_; |
649 } | 678 } |
650 int mask_tex_coord_offset_location() const { | 679 int mask_tex_coord_offset_location() const { |
(...skipping 12 matching lines...) Expand all Loading... | |
663 int color_offset_location_; | 692 int color_offset_location_; |
664 }; | 693 }; |
665 | 694 |
666 class FragmentShaderRGBATexAlphaColorMatrixAA : public FragmentTexBlendMode { | 695 class FragmentShaderRGBATexAlphaColorMatrixAA : public FragmentTexBlendMode { |
667 public: | 696 public: |
668 FragmentShaderRGBATexAlphaColorMatrixAA(); | 697 FragmentShaderRGBATexAlphaColorMatrixAA(); |
669 std::string GetShaderString( | 698 std::string GetShaderString( |
670 TexCoordPrecision precision, SamplerType sampler) const; | 699 TexCoordPrecision precision, SamplerType sampler) const; |
671 static std::string GetShaderHead(); | 700 static std::string GetShaderHead(); |
672 static std::string GetShaderBody(); | 701 static std::string GetShaderBody(); |
673 | 702 void FillLocations(ShaderLocations* locations) const; |
674 void Init(gpu::gles2::GLES2Interface* context, | 703 void Init(gpu::gles2::GLES2Interface* context, |
675 unsigned program, | 704 unsigned program, |
676 int* base_uniform_index); | 705 int* base_uniform_index); |
677 int alpha_location() const { return alpha_location_; } | 706 int alpha_location() const { return alpha_location_; } |
678 int sampler_location() const { return sampler_location_; } | 707 int sampler_location() const { return sampler_location_; } |
679 int color_matrix_location() const { return color_matrix_location_; } | 708 int color_matrix_location() const { return color_matrix_location_; } |
680 int color_offset_location() const { return color_offset_location_; } | 709 int color_offset_location() const { return color_offset_location_; } |
681 | 710 |
682 private: | 711 private: |
683 int sampler_location_; | 712 int sampler_location_; |
684 int alpha_location_; | 713 int alpha_location_; |
685 int color_matrix_location_; | 714 int color_matrix_location_; |
686 int color_offset_location_; | 715 int color_offset_location_; |
687 }; | 716 }; |
688 | 717 |
689 class FragmentShaderRGBATexAlphaMaskColorMatrix : public FragmentTexBlendMode { | 718 class FragmentShaderRGBATexAlphaMaskColorMatrix : public FragmentTexBlendMode { |
690 public: | 719 public: |
691 FragmentShaderRGBATexAlphaMaskColorMatrix(); | 720 FragmentShaderRGBATexAlphaMaskColorMatrix(); |
692 std::string GetShaderString( | 721 std::string GetShaderString( |
693 TexCoordPrecision precision, SamplerType sampler) const; | 722 TexCoordPrecision precision, SamplerType sampler) const; |
694 static std::string GetShaderHead(); | 723 static std::string GetShaderHead(); |
695 static std::string GetShaderBody(); | 724 static std::string GetShaderBody(bool need); |
696 | 725 void FillLocations(ShaderLocations* locations) const; |
697 void Init(gpu::gles2::GLES2Interface* context, | 726 void Init(gpu::gles2::GLES2Interface* context, |
698 unsigned program, | 727 unsigned program, |
699 int* base_uniform_index); | 728 int* base_uniform_index); |
700 int alpha_location() const { return alpha_location_; } | 729 int alpha_location() const { return alpha_location_; } |
701 int sampler_location() const { return sampler_location_; } | 730 int sampler_location() const { return sampler_location_; } |
702 int mask_sampler_location() const { return mask_sampler_location_; } | 731 int mask_sampler_location() const { return mask_sampler_location_; } |
703 int mask_tex_coord_scale_location() const { | 732 int mask_tex_coord_scale_location() const { |
704 return mask_tex_coord_scale_location_; | 733 return mask_tex_coord_scale_location_; |
705 } | 734 } |
706 int mask_tex_coord_offset_location() const { | 735 int mask_tex_coord_offset_location() const { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
843 int tex_transform_location_; | 872 int tex_transform_location_; |
844 int frequency_location_; | 873 int frequency_location_; |
845 int color_location_; | 874 int color_location_; |
846 | 875 |
847 DISALLOW_COPY_AND_ASSIGN(FragmentShaderCheckerboard); | 876 DISALLOW_COPY_AND_ASSIGN(FragmentShaderCheckerboard); |
848 }; | 877 }; |
849 | 878 |
850 } // namespace cc | 879 } // namespace cc |
851 | 880 |
852 #endif // CC_OUTPUT_SHADER_H_ | 881 #endif // CC_OUTPUT_SHADER_H_ |
OLD | NEW |