OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #include "cc/resources/video_resource_updater.h" | 5 #include "cc/resources/video_resource_updater.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. | 507 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. |
508 size_t upload_image_stride = | 508 size_t upload_image_stride = |
509 MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u); | 509 MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u); |
510 | 510 |
511 bool needs_conversion = false; | 511 bool needs_conversion = false; |
512 int shift = 0; | 512 int shift = 0; |
513 | 513 |
514 // LUMINANCE_F16 uses half-floats, so we always need a conversion step. | 514 // LUMINANCE_F16 uses half-floats, so we always need a conversion step. |
515 if (plane_resource.resource_format() == LUMINANCE_F16) { | 515 if (plane_resource.resource_format() == LUMINANCE_F16) { |
516 needs_conversion = true; | 516 needs_conversion = true; |
517 | |
518 // If the input data was 9 or 10 bit, and we output to half-floats, | |
519 // then we used the OR path below, which means that we need to | |
520 // adjust the resource offset and multiplier accordingly. If the | |
521 // input data uses more than 10 bits, it will already be normalized | |
522 // to 0.0..1.0, so there is no need to do anything. | |
523 if (bits_per_channel <= 10) { | |
524 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the | |
525 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). | |
526 // | |
527 // Half-floats are evaluated as: | |
528 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); | |
529 // | |
530 // In our case the exponent is 14 (since we or with 0x3800) and | |
531 // pow(2.0, 14-25) * 0x400 evaluates to 0.5 (our offset) and | |
532 // pow(2.0, 14-25) * fraction is [0..0.49951171875] for 10-bit and | |
533 // [0..0.24951171875] for 9-bit. | |
534 // | |
535 // https://en.wikipedia.org/wiki/Half-precision_floating-point_format | |
536 // | |
537 // PLEASE NOTE: | |
538 // All planes are assumed to use the same multiplier/offset. | |
539 external_resources.offset = 0.5f; | |
540 // Max value from input data. | |
541 int max_input_value = (1 << bits_per_channel) - 1; | |
542 // 2 << 11 = 2048 would be 1.0 with our exponent. | |
543 external_resources.multiplier = 2048.0 / max_input_value; | |
544 } | |
545 } else if (bits_per_channel > 8) { | 517 } else if (bits_per_channel > 8) { |
546 // If bits_per_channel > 8 and we can't use LUMINANCE_F16, we need to | 518 // If bits_per_channel > 8 and we can't use LUMINANCE_F16, we need to |
547 // shift the data down and create an 8-bit texture. | 519 // shift the data down and create an 8-bit texture. |
548 needs_conversion = true; | 520 needs_conversion = true; |
549 shift = bits_per_channel - 8; | 521 shift = bits_per_channel - 8; |
550 } | 522 } |
551 const uint8_t* pixels; | 523 const uint8_t* pixels; |
552 if (static_cast<int>(upload_image_stride) == video_stride_bytes && | 524 if (static_cast<int>(upload_image_stride) == video_stride_bytes && |
553 !needs_conversion) { | 525 !needs_conversion) { |
554 pixels = video_frame->data(i); | 526 pixels = video_frame->data(i); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 } | 566 } |
595 } | 567 } |
596 pixels = &upload_pixels_[0]; | 568 pixels = &upload_pixels_[0]; |
597 } | 569 } |
598 | 570 |
599 resource_provider_->CopyToResource(plane_resource.resource_id(), pixels, | 571 resource_provider_->CopyToResource(plane_resource.resource_id(), pixels, |
600 resource_size_pixels); | 572 resource_size_pixels); |
601 plane_resource.SetUniqueId(video_frame->unique_id(), i); | 573 plane_resource.SetUniqueId(video_frame->unique_id(), i); |
602 } | 574 } |
603 | 575 |
| 576 if (plane_resource.resource_format() == LUMINANCE_F16) { |
| 577 // If the input data was 9 or 10 bit, and we output to half-floats, |
| 578 // then we used the OR path above, which means that we need to |
| 579 // adjust the resource offset and multiplier accordingly. If the |
| 580 // input data uses more than 10 bits, it will already be normalized |
| 581 // to 0.0..1.0, so there is no need to do anything. |
| 582 if (bits_per_channel <= 10) { |
| 583 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the |
| 584 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). |
| 585 // |
| 586 // Half-floats are evaluated as: |
| 587 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); |
| 588 // |
| 589 // In our case the exponent is 14 (since we or with 0x3800) and |
| 590 // pow(2.0, 14-25) * 0x400 evaluates to 0.5 (our offset) and |
| 591 // pow(2.0, 14-25) * fraction is [0..0.49951171875] for 10-bit and |
| 592 // [0..0.24951171875] for 9-bit. |
| 593 // |
| 594 // https://en.wikipedia.org/wiki/Half-precision_floating-point_format |
| 595 // |
| 596 // PLEASE NOTE: |
| 597 // All planes are assumed to use the same multiplier/offset. |
| 598 external_resources.offset = 0.5f; |
| 599 // Max value from input data. |
| 600 int max_input_value = (1 << bits_per_channel) - 1; |
| 601 // 2 << 11 = 2048 would be 1.0 with our exponent. |
| 602 external_resources.multiplier = 2048.0 / max_input_value; |
| 603 } |
| 604 } |
604 | 605 |
605 // VideoResourceUpdater shares a context with the compositor so a | 606 // VideoResourceUpdater shares a context with the compositor so a |
606 // sync token is not required. | 607 // sync token is not required. |
607 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), | 608 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), |
608 resource_provider_->GetResourceTextureTarget( | 609 resource_provider_->GetResourceTextureTarget( |
609 plane_resource.resource_id())); | 610 plane_resource.resource_id())); |
610 mailbox.set_color_space(video_frame->ColorSpace()); | 611 mailbox.set_color_space(video_frame->ColorSpace()); |
611 external_resources.mailboxes.push_back(mailbox); | 612 external_resources.mailboxes.push_back(mailbox); |
612 external_resources.release_callbacks.push_back(base::Bind( | 613 external_resources.release_callbacks.push_back(base::Bind( |
613 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); | 614 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 if (lost_resource) { | 762 if (lost_resource) { |
762 resource_it->clear_refs(); | 763 resource_it->clear_refs(); |
763 updater->DeleteResource(resource_it); | 764 updater->DeleteResource(resource_it); |
764 return; | 765 return; |
765 } | 766 } |
766 | 767 |
767 resource_it->remove_ref(); | 768 resource_it->remove_ref(); |
768 } | 769 } |
769 | 770 |
770 } // namespace cc | 771 } // namespace cc |
OLD | NEW |