Provide origin info for ExternalTexture

Current ExternalTexture visible related info only contains width and height.

But not all the visible rect started at (0, 0). This CL add visibleOrigin to contain origin info and record (width, height) in
visibleSize

Bug: chromium:1361363
Change-Id: I3d8931e490c97740f152653383f07d0a2d984dd3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/108024
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
diff --git a/dawn.json b/dawn.json
index f58121f..817991f 100644
--- a/dawn.json
+++ b/dawn.json
@@ -1331,6 +1331,7 @@
     },
     "extent 2D": {
         "category": "structure",
+        "tags": ["dawn"],
         "_TODO": "crbug.com/1316671: Remove default value of 'width' after chromium side chagnes landed",
         "members": [
             {"name": "width", "type": "uint32_t", "default": 0},
@@ -1370,7 +1371,8 @@
             {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
             {"name": "plane 0", "type": "texture view"},
             {"name": "plane 1", "type": "texture view", "optional": true},
-            {"name": "visible rect", "type": "extent 2D"},
+            {"name": "visible origin", "type": "origin 2D"},
+            {"name": "visible size", "type": "extent 2D"},
             {"name": "do yuv to rgb conversion only", "type": "bool", "default": "false"},
             {"name": "yuv to rgb conversion matrix", "type": "float", "annotation": "const*",
                 "length": 12, "optional": true},
@@ -1562,6 +1564,14 @@
             {"name": "z", "type": "uint32_t", "default": "0"}
         ]
     },
+    "origin 2D": {
+        "category": "structure",
+        "tags": ["dawn"],
+        "members": [
+            {"name": "x", "type": "uint32_t", "default": "0"},
+            {"name": "y", "type": "uint32_t", "default": "0"}
+        ]
+    },
     "pipeline layout": {
         "category": "object",
         "methods": [
diff --git a/src/dawn/native/CopyTextureForBrowserHelper.cpp b/src/dawn/native/CopyTextureForBrowserHelper.cpp
index 5d63725..011ca85 100644
--- a/src/dawn/native/CopyTextureForBrowserHelper.cpp
+++ b/src/dawn/native/CopyTextureForBrowserHelper.cpp
@@ -711,17 +711,19 @@
     // Validate source
     DAWN_TRY(device->ValidateObject(source->externalTexture));
     DAWN_TRY(source->externalTexture->ValidateCanUseInSubmitNow());
-    const Extent2D& sourceVisibleRect = source->externalTexture->GetVisibleRect();
+
+    const Extent2D& sourceVisibleSize = source->externalTexture->GetVisibleSize();
+
     // All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid
     // overflows.
     DAWN_INVALID_IF(
         static_cast<uint64_t>(source->origin.x) + static_cast<uint64_t>(copySize->width) >
-                static_cast<uint64_t>(sourceVisibleRect.width) ||
+                static_cast<uint64_t>(sourceVisibleSize.width) ||
             static_cast<uint64_t>(source->origin.y) + static_cast<uint64_t>(copySize->height) >
-                static_cast<uint64_t>(sourceVisibleRect.height) ||
+                static_cast<uint64_t>(sourceVisibleSize.height) ||
             static_cast<uint64_t>(source->origin.z) > 0,
         "Texture copy range (origin: %s, copySize: %s) touches outside of %s visible size (%s).",
-        &source->origin, copySize, source->externalTexture, &sourceVisibleRect);
+        &source->origin, copySize, source->externalTexture, &sourceVisibleSize);
     DAWN_INVALID_IF(source->origin.z > 0, "Source has a non-zero z origin (%u).", source->origin.z);
     DAWN_INVALID_IF(
         options->internalUsage && !device->HasFeature(Feature::DawnInternalUsages),
@@ -747,8 +749,8 @@
                                            const CopyTextureForBrowserOptions* options) {
     TextureInfo info;
     info.origin = source->origin;
-    const Extent2D& visibleRect = source->externalTexture->GetVisibleRect();
-    info.size = {visibleRect.width, visibleRect.height, 1};
+    const Extent2D& visibleSize = source->externalTexture->GetVisibleSize();
+    info.size = {visibleSize.width, visibleSize.height, 1};
 
     RenderPipelineBase* pipeline;
     DAWN_TRY_ASSIGN(pipeline, GetOrCreateCopyExternalTextureForBrowserPipeline(
diff --git a/src/dawn/native/ExternalTexture.cpp b/src/dawn/native/ExternalTexture.cpp
index 14ea84f..edc9a35 100644
--- a/src/dawn/native/ExternalTexture.cpp
+++ b/src/dawn/native/ExternalTexture.cpp
@@ -99,20 +99,25 @@
         }
     }
 
-    // TODO(crbug.com/1316671): visibleRect must have valid value after chromium side changes
+    // TODO(crbug.com/1316671): visible size width must have valid value after chromium side changes
     // landed.
-    if (descriptor->visibleRect.width > 0) {
-        DAWN_INVALID_IF(descriptor->visibleRect.width == 0 || descriptor->visibleRect.height == 0,
-                        "VisibleRect(%u, %u) have 0 on width or height.",
-                        descriptor->visibleRect.width, descriptor->visibleRect.height);
+    if (descriptor->visibleSize.width > 0) {
+        DAWN_INVALID_IF(descriptor->visibleSize.width == 0 || descriptor->visibleSize.height == 0,
+                        "VisibleSize %s have 0 on width or height.", &descriptor->visibleSize);
 
-        Extent3D maxVisibleRectSize = descriptor->plane0->GetTexture()->GetSize();
-        DAWN_INVALID_IF(descriptor->visibleRect.width > maxVisibleRectSize.width ||
-                            descriptor->visibleRect.height > maxVisibleRectSize.height,
-                        "VisibleRect(%u, %u) is exceed the max visible rect size, defined by "
-                        "Plane0 size (%u, %u).",
-                        descriptor->visibleRect.width, descriptor->visibleRect.height,
-                        maxVisibleRectSize.width, maxVisibleRectSize.height);
+        const Extent3D textureSize = descriptor->plane0->GetTexture()->GetSize();
+        DAWN_INVALID_IF(
+            descriptor->visibleSize.width > textureSize.width ||
+                descriptor->visibleSize.height > textureSize.height,
+            "VisibleSize %s is exceed the texture size, defined by Plane0 size (%u, %u).",
+            &descriptor->visibleSize, textureSize.width, textureSize.height);
+        DAWN_INVALID_IF(
+            descriptor->visibleOrigin.x > textureSize.width - descriptor->visibleSize.width ||
+                descriptor->visibleOrigin.y > textureSize.height - descriptor->visibleSize.height,
+            "VisibleRect[Origin: %s, Size: %s] is exceed the texture size, defined by "
+            "Plane0 size (%u, %u).",
+            &descriptor->visibleOrigin, &descriptor->visibleSize, textureSize.width,
+            textureSize.height);
     }
 
     return {};
@@ -131,7 +136,8 @@
 ExternalTextureBase::ExternalTextureBase(DeviceBase* device,
                                          const ExternalTextureDescriptor* descriptor)
     : ApiObjectBase(device, descriptor->label),
-      mVisibleRect(descriptor->visibleRect),
+      mVisibleOrigin(descriptor->visibleOrigin),
+      mVisibleSize(descriptor->visibleSize),
       mState(ExternalTextureState::Alive) {
     GetObjectTrackingList()->Track(this);
 }
@@ -252,9 +258,14 @@
     return ObjectType::ExternalTexture;
 }
 
-const Extent2D& ExternalTextureBase::GetVisibleRect() const {
+const Extent2D& ExternalTextureBase::GetVisibleSize() const {
     ASSERT(!IsError());
-    return mVisibleRect;
+    return mVisibleSize;
+}
+
+const Origin2D& ExternalTextureBase::GetVisibleOrigin() const {
+    ASSERT(!IsError());
+    return mVisibleOrigin;
 }
 
 }  // namespace dawn::native
diff --git a/src/dawn/native/ExternalTexture.h b/src/dawn/native/ExternalTexture.h
index 6ea47e8..d0d5a28 100644
--- a/src/dawn/native/ExternalTexture.h
+++ b/src/dawn/native/ExternalTexture.h
@@ -49,7 +49,9 @@
     BufferBase* GetParamsBuffer() const;
     const std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat>& GetTextureViews() const;
     ObjectType GetType() const override;
-    const Extent2D& GetVisibleRect() const;
+
+    const Extent2D& GetVisibleSize() const;
+    const Origin2D& GetVisibleOrigin() const;
 
     MaybeError ValidateCanUseInSubmitNow() const;
     static ExternalTextureBase* MakeError(DeviceBase* device);
@@ -74,9 +76,10 @@
     Ref<BufferBase> mParamsBuffer;
     std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews;
 
-    // TODO(dawn:1082) Use the visible rect in the external texture shader code to sample
-    // video content.
-    Extent2D mVisibleRect;
+    // TODO(dawn:1082) Use the visible size and origin in the external texture shader
+    // code to sample video content.
+    Origin2D mVisibleOrigin;
+    Extent2D mVisibleSize;
 
     ExternalTextureState mState;
 };
diff --git a/src/dawn/native/webgpu_absl_format.cpp b/src/dawn/native/webgpu_absl_format.cpp
index a33ab42..7df36ed 100644
--- a/src/dawn/native/webgpu_absl_format.cpp
+++ b/src/dawn/native/webgpu_absl_format.cpp
@@ -71,6 +71,18 @@
 }
 
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const Origin2D* value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    if (value == nullptr) {
+        s->Append("[null]");
+        return {true};
+    }
+    s->Append(absl::StrFormat("[Origin2D x:%u, y:%u]", value->x, value->y));
+    return {true};
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const Origin3D* value,
     const absl::FormatConversionSpec& spec,
     absl::FormatSink* s) {
diff --git a/src/dawn/native/webgpu_absl_format.h b/src/dawn/native/webgpu_absl_format.h
index 23964ad..d01da56 100644
--- a/src/dawn/native/webgpu_absl_format.h
+++ b/src/dawn/native/webgpu_absl_format.h
@@ -41,6 +41,12 @@
     const absl::FormatConversionSpec& spec,
     absl::FormatSink* s);
 
+struct Origin2D;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const Origin2D* value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
 struct Origin3D;
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const Origin3D* value,
diff --git a/src/dawn/tests/end2end/CopyExternalTextureForBrowserTests.cpp b/src/dawn/tests/end2end/CopyExternalTextureForBrowserTests.cpp
index 549e712..66024c3 100644
--- a/src/dawn/tests/end2end/CopyExternalTextureForBrowserTests.cpp
+++ b/src/dawn/tests/end2end/CopyExternalTextureForBrowserTests.cpp
@@ -114,7 +114,8 @@
         externalDesc.plane0 = externalTexturePlane0.CreateView();
         externalDesc.plane1 = externalTexturePlane1.CreateView();
 
-        externalDesc.visibleRect = {kWidth, kHeight};
+        externalDesc.visibleOrigin = {0, 0};
+        externalDesc.visibleSize = {kWidth, kHeight};
 
         // Import the external texture
         return this->device.CreateExternalTexture(&externalDesc);
diff --git a/src/dawn/tests/unittests/validation/CopyTextureForBrowserTests.cpp b/src/dawn/tests/unittests/validation/CopyTextureForBrowserTests.cpp
index 96fc533..e28dfc4 100644
--- a/src/dawn/tests/unittests/validation/CopyTextureForBrowserTests.cpp
+++ b/src/dawn/tests/unittests/validation/CopyTextureForBrowserTests.cpp
@@ -63,7 +63,8 @@
 
     externalDesc.plane0 = view;
 
-    externalDesc.visibleRect = {width, height};
+    externalDesc.visibleOrigin = {0, 0};
+    externalDesc.visibleSize = {width, height};
 
     // Import the external texture
     return device.CreateExternalTexture(&externalDesc);
diff --git a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
index 55d9499..bd2392b 100644
--- a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
+++ b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
@@ -582,7 +582,7 @@
 }
 
 // Test create external texture with too large visible rect results in error.
-TEST_F(ExternalTextureTest, CreateExternalTextureWithErrorVisibleRect) {
+TEST_F(ExternalTextureTest, CreateExternalTextureWithErrorVisibleOriginOrSize) {
     // Control case should succeed.
     {
         wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
@@ -590,29 +590,56 @@
 
         wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
         externalDesc.plane0 = texture.CreateView();
-        externalDesc.visibleRect = {texture.GetWidth(), texture.GetHeight()};
+        externalDesc.visibleOrigin = {0, 0};
+        externalDesc.visibleSize = {texture.GetWidth(), texture.GetHeight()};
         device.CreateExternalTexture(&externalDesc);
     }
 
-    // VisibleRect is OOB on width
+    // VisibleOrigin is OOB on x
     {
         wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
         wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
 
         wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
         externalDesc.plane0 = texture.CreateView();
-        externalDesc.visibleRect = {texture.GetWidth() + 1, texture.GetHeight()};
+        externalDesc.visibleOrigin = {1, 0};
+        externalDesc.visibleSize = {texture.GetWidth(), texture.GetHeight()};
         ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
     }
 
-    // VisibleRect is OOB on height
+    // VisibleOrigin is OOB on y
     {
         wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
         wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
 
         wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
         externalDesc.plane0 = texture.CreateView();
-        externalDesc.visibleRect = {texture.GetWidth(), texture.GetHeight() + 1};
+        externalDesc.visibleOrigin = {0, 1};
+        externalDesc.visibleSize = {texture.GetWidth(), texture.GetHeight()};
+        ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
+    }
+
+    // VisibleSize is OOB on width
+    {
+        wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
+        wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
+
+        wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
+        externalDesc.plane0 = texture.CreateView();
+        externalDesc.visibleOrigin = {0, 0};
+        externalDesc.visibleSize = {texture.GetWidth() + 1, texture.GetHeight()};
+        ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
+    }
+
+    // VisibleSize is OOB on height
+    {
+        wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
+        wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
+
+        wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
+        externalDesc.plane0 = texture.CreateView();
+        externalDesc.visibleOrigin = {0, 0};
+        externalDesc.visibleSize = {texture.GetWidth(), texture.GetHeight() + 1};
         ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
     }
 }